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));