laravel 项目 http 改造 https 时,asset() 静态文件引入解决方案

966 阅读2分钟

laravel 的 asset() 方法,默认并未去判断 http 或 https,默认是 http。

除非传递第二个参数为 true,会生成 https 链接

我们项目中,不可能因为一个 https,把所有连接全部改掉。本地的话,我们还得使用 http。

搜索了一些资料,更好的方案,应该如下: .env:

	# 是否 HTTPS 环境
	# IS_HTTPS=true

app/Providers/AppServiceProvider.php

    // HTTPS 访问
    if(env('IS_HTTPS')){
        URL::forceScheme('https');
    }

.env 开启 IS_HTTPS,则 assert() 会生成 https 链接

补充: 我们在上面的 AppServiceProvider 中采用 URL::forceScheme('https'),强制使用了 https 协议

我们在控制器、模板中,使用 url() 或 asset() 确实可以生成 https 的 url。

但今天发现项目中一个问题,支付宝支付的异步通知并未有日志记录,也就是说,支付宝的异步通知没有获取到。通过查看日志,发现发送给支付宝的异步通知的链接还是 http。

测试了半天,采用 url('test') 在控制器、模板中测试输出,确实是 'https',但是我们的异步通知链接确实是 'http'

最后排查,因为我们的支付宝异步链接写在了自定义的一个 HelperProvider 引入的常量定义文件中:
	define('ALIPAY_NOTIFY_URL', url('/payment/alipay/notify'));

看着没有任何问题啊!为什么生成的 url 不是 'https'?

突然想到了之前看过 laravel 源码,里面关于启动脚本,加载的各种启动文件的顺序,应该是 AppServiceProvider 的加载或执行顺序,在 HelperProvider 后面,导致:

    if(env('IS_HTTPS')){
        URL::forceScheme('https');
    }

代码还未执行!控制器、模板里的 url(),已经是执行后的结果!

/*
	启动脚本顺序:
        \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
        \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
        \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
        \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
        \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
        \Illuminate\Foundation\Bootstrap\BootProviders::class,
	    .env 等环境变量
	    config 配置
	    异常
	    Facade 注册
	    注册 Providers
	    启动 Providers
 */

综上分析:
	我们得小心了,我们的 config/ 目录下的配置文件里,使用 url() 时,生成的也不是 'https' 链接。

最终修改,强制改为 https 链接即可:
	define('ALIPAY_NOTIFY_URL', url('/payment/alipay/notify', [], true));