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文件环境检测后设置UrlGeneratorforcedSchema属性的问题。

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

在 Laravel 5 中链接 Css 和 Js 文件 Summernote 资产的正确方法

在 Laravel 中将 Public 添加到资产路径

无法在新的 Homestead 安装上编译 Laravel 资产

将 Laravel 路由参数传递给 JavaScript

在 laravel 中使用前缀后,asset('assets') 返回错误的目录