laravel 资产()方法不返回 https
Posted
技术标签:
【中文标题】laravel 资产()方法不返回 https【英文标题】:laravel asset() method doesn't return https 【发布时间】:2017-04-04 23:24:56 【问题描述】:我正在使用asset()
public 方法在 laravel 中生成正确的 url。
在文档中它说:
所以理论上它应该自己检测正确的方案。
但在代码中我看到:https://github.com/illuminate/routing/blob/master/UrlGenerator.php#L210
public function asset($path, $secure = null)
安全的默认值为空。所以这个方法对http/https都不好。
我在这里错过了什么?
我正在使用反向代理,可能是因为这个吗?
【问题讨论】:
在没有代理的情况下检查它没有意义吗?喜欢curl http://localhost/page_that_contains_the_asset
。
@AlexBlex 我不明白这个问题。
如果您可以通过 .htaccess 文件强制使用 HTTPS,我不会像人们建议的那样更改代码中的任何内容。
@ThomasYates 我在前面使用 ssl 反向代理,但是 laravel 没有通过asset() 返回正确的 url。带着这个问题,我试图理解为什么。看来反向代理搞砸了。
【参考方案1】:
从 GitHub 可以看出,asset
方法正在调用 getScheme
来确定方案应该是什么。
https://github.com/illuminate/routing/blob/master/UrlGenerator.php#L303
public function formatScheme($secure = null)
if (! is_null($secure))
return $secure ? 'https://' : 'http://';
if (is_null($this->cachedScheme))
$this->cachedScheme = $this->forceScheme ?: $this->request->getScheme().'://';
return $this->cachedScheme;
所以如果你不提供asset
第二个参数$secure
那么它使用请求方案。否则,您可以提供$secure
以强制使用所需的方案,而不管请求中的方案是什么。
如果您查看代码,您会发现如果$secure
为空且未设置缓存,则缓存设置为请求方案(即$this->request->getScheme()
)并因此返回。
【讨论】:
我明白了,这是有道理的。所以我的问题是this->request->getScheme()
没有意识到我正在使用 https。可能是因为反向代理。
确实可以是反向代理,但我认为 Apache 也可以配置为在 https 上反向,因此您可能需要在那里进行一些调整。尝试转储请求数据,看看最后一个节点是什么,如果是 http 或 https,你会得到什么。
我正在使用 nginx,但这不是重点。我有< client browser > < ssl nginx > < 80 nginx > < laravel >
我不想在 nginx 之间强制使用 https,因为它在同一台服务器上没有必要。但我希望 laravel 能够正确查看架构
哦那个死地方:) 没有人回答任何关于服务器故障的问题。无论如何,我在 nginx conf 中发现了问题proxy_set_header X-Forwarded-Proto https
【参考方案2】:
你要找的不是secure_asset
吗?
https://laravel.com/docs/5.3/helpers#method-secure-asset
【讨论】:
不,这只会强制使用 https。我想要等效于//
的解决方案
@salivan 不是最好的解决方案,但如果你想要的是//
,为什么不将asset()
url 中的“http”替换为“”,因为它总是输出以@987654326 开头的url @?【参考方案3】:
在同一个文件中,您有一个使用 $secure 参数的 getScheme() 方法的定义。
如果 $secure 参数是默认的 null
值,则该方案要么从当前方案中猜测,要么从先前保存的方案中检索(如果它没有被 forceSchema() 强制)。
你可以告诉 $secure 参数是这样工作的:
true
将强制 https
false
会强制http
null
将使用最佳方案,根据当前方案猜测
这是 getScheme() 方法的代码:
protected function getScheme($secure)
if (is_null($secure))
if (is_null($this->cachedSchema))
$this->cachedSchema = $this->forceSchema ?: $this->request->getScheme().'://';
return $this->cachedSchema;
return $secure ? 'https://' : 'http://';
【讨论】:
这与我的回答有何不同? 在编辑我的答案时,我没有看到你已经回答了。 是的,我猜他们离得太近了 ;-) 我明白了,所以我的问题是this->request->getScheme()
无法正确猜测架构,可能是因为反向代理?
也许吧。但是您能猜出您当前的方案并将其作为第二个参数传递给该方法吗?【参考方案4】:
请停止为已经存在的事情编写代码。 有一个 ASSET_URL 环境变量。使用它。
ASSET_URL=https://your.app.url #in env for production
ASSET_URL=http://your.app.url #in env for local development
(https://***.com/a/68287406/7481663)
【讨论】:
【参考方案5】:如果有人像我一样陷入同样的问题,为了让asset
函数获得正确的架构,您必须启用TrustedProxies
。
在 laravel 中有一个中间件可以在 \App\Http\Middleware\TrustedProxies
中为您执行此操作,但您必须将其包含在默认中间件中才能生效。
Laravel 使用 fideloper/TrustedProxy
包在 Request
对象中设置 trustedProxies
数组,检查该对象以批准标题中提供的 X-Forwarded-Proto
。
您可以查看以下链接以获取更多详细信息
Explains in Laravel Trusted Proxy in details
For Setting it up
【讨论】:
【参考方案6】:是的,这是因为反向代理会终止 SSL,这意味着浏览器请求 https,但从代理到应用程序的请求是 http。这有很多好处(提高了性能),但确实有这种副作用。
我认为该解决方案将作为一个环境变量,告诉您强制使用 https(在登台或生产中使用网络时)或在例如本地开发。
我认为是最有效的。我这样说是因为您的应用永远不会知道何时使用 https。
【讨论】:
【参考方案7】:我在 Laravel 4.2 中构建的一些遗留系统中进行了一些维护,并在这种情况下绊倒了。
看了下Generators是如何实例化和使用的,我解决了在应用程序的start.php
文件环境检测后设置UrlGenerator
forcedSchema
属性的问题。
// The if condition depends on what identifies your https host
if( str_contains($_SERVER['HTTP_HOST'], 'secure_app_host_fragment'))
$app['url']->forceSchema('https');
代码: https://github.com/laravel/framework/blob/7d9e7068c49f945385673014d4cba4de28accd5e/src/Illuminate/Routing/UrlGenerator.php#L204
【讨论】:
以上是关于laravel 资产()方法不返回 https的主要内容,如果未能解决你的问题,请参考以下文章
在 Laravel 5 中链接 Css 和 Js 文件 Summernote 资产的正确方法