route () 函数将 https 渲染成了 http

部署到 Heroku 上后发现 route() 函数将 https 渲染成了 http
file
没找到问题所有,请知道的同学如果有时间帮忙解答下.
谢谢.

《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 5

追了一下源码,渲染成 http:// 的原因可能如下:
route 函数的定义在 /vendor/laravel/framework/src/Illuminate/Routing/Redirector.php 中:

/**
 * Create a new redirect response to a named route.
 *
 */
public function route($route, $parameters = [], $status = 302, $headers = [])
{
    return $this->to($this->generator->route($route, $parameters), $status, $headers);
}

注意其中的 to 方法:

/**
 * Create a new redirect response to the given path.
 *
 */
public function to($path, $status = 302, $headers = [], $secure = null)
{
    return $this->createRedirect($this->generator->to($path, [], $secure), $status, $headers);
}

传递了一个 $secure 参数给到 generatorto 方法,且默认值为 null ,找到 /vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php 中的定义:

/**
 * Generate an absolute URL to the given path.
 */
public function to($path, $extra = [], $secure = null)
{
    ……
    $root = $this->formatRoot($this->formatScheme($secure));
}

$secure 参数传递到了 formatScheme 方法,找到定义:

/**
 * Get the default scheme for a raw URL.
 */
public function formatScheme($secure)
{
    if (! is_null($secure)) {
        return $secure ? 'https://' : 'http://';
    }

    if (is_null($this->cachedSchema)) {
        $this->cachedSchema = $this->forceScheme ?: $this->request->getScheme().'://';
    }
    return $this->cachedSchema;
}

可以看到,当 $secure 不为空时,会根据 $secure 的值来选择 https 还是 http;如果 $secure 为空,则会去检查 $cachedSchema 的值并返回,如果 $cachedSchema 的值为空,则会根据 $forceScheme 的值来进行设定,如果 $forceScheme 的值为空,则会调用 getScheme 方法来进行相关的设置,找到 /vendor/symfony/http-foundation/Request.php 中的定义:

/**
 * Gets the request's scheme.
 */
public function getScheme()
{
    return $this->isSecure() ? 'https' : 'http';
}

此处会通过 isSecure 方法来检查安全性配置:

/**
 * Checks whether the request is secure or not.
 *
 * This method can read the client protocol from the "X-Forwarded-Proto" header
 * when trusted proxies were set via "setTrustedProxies()".
 *
 * The "X-Forwarded-Proto" header must contain the protocol: "https" or "http".
 *
 * If your reverse proxy uses a different header name than "X-Forwarded-Proto"
 * ("SSL_HTTPS" for instance), configure it via the $trustedHeaderSet
 * argument of the Request::setTrustedProxies() method instead.
 *
 * @return bool
 */
public function isSecure()
{
    …… 重点看注释
}

如果使用了教程中的默认设置,最终返回的链接是否启用 https:// 是由服务器的相关配置决定的。 herokuapp.com 这个域名是有 SSL 证书的,如果要渲染出 https:// 链接,方法有两个:1.修改 heroku 上的相关配置;2.设定 $forceScheme 的值,强制启用 HTTPS

6年前 评论
堂堂糖唐

最简单的处理方式,修改nginx代理fpm配置:

server {
    listen      80;
    server_name www.a.com;
    root        /www/code;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass    127.0.0.1:9000;
        fastcgi_param   HTTPS on;
        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include         fastcgi_params;
    }
}

注意fastcgi_param HTTPS on;

4年前 评论
Echos

应该是跟你的服务器配置有关系,具体原因百度你应该可以得到你想要的答案

6年前 评论
Shuyi

.env文件里面, APP_URLHTTP:// 改成 HTTPS:// 试试?

6年前 评论

追了一下源码,渲染成 http:// 的原因可能如下:
route 函数的定义在 /vendor/laravel/framework/src/Illuminate/Routing/Redirector.php 中:

/**
 * Create a new redirect response to a named route.
 *
 */
public function route($route, $parameters = [], $status = 302, $headers = [])
{
    return $this->to($this->generator->route($route, $parameters), $status, $headers);
}

注意其中的 to 方法:

/**
 * Create a new redirect response to the given path.
 *
 */
public function to($path, $status = 302, $headers = [], $secure = null)
{
    return $this->createRedirect($this->generator->to($path, [], $secure), $status, $headers);
}

传递了一个 $secure 参数给到 generatorto 方法,且默认值为 null ,找到 /vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php 中的定义:

/**
 * Generate an absolute URL to the given path.
 */
public function to($path, $extra = [], $secure = null)
{
    ……
    $root = $this->formatRoot($this->formatScheme($secure));
}

$secure 参数传递到了 formatScheme 方法,找到定义:

/**
 * Get the default scheme for a raw URL.
 */
public function formatScheme($secure)
{
    if (! is_null($secure)) {
        return $secure ? 'https://' : 'http://';
    }

    if (is_null($this->cachedSchema)) {
        $this->cachedSchema = $this->forceScheme ?: $this->request->getScheme().'://';
    }
    return $this->cachedSchema;
}

可以看到,当 $secure 不为空时,会根据 $secure 的值来选择 https 还是 http;如果 $secure 为空,则会去检查 $cachedSchema 的值并返回,如果 $cachedSchema 的值为空,则会根据 $forceScheme 的值来进行设定,如果 $forceScheme 的值为空,则会调用 getScheme 方法来进行相关的设置,找到 /vendor/symfony/http-foundation/Request.php 中的定义:

/**
 * Gets the request's scheme.
 */
public function getScheme()
{
    return $this->isSecure() ? 'https' : 'http';
}

此处会通过 isSecure 方法来检查安全性配置:

/**
 * Checks whether the request is secure or not.
 *
 * This method can read the client protocol from the "X-Forwarded-Proto" header
 * when trusted proxies were set via "setTrustedProxies()".
 *
 * The "X-Forwarded-Proto" header must contain the protocol: "https" or "http".
 *
 * If your reverse proxy uses a different header name than "X-Forwarded-Proto"
 * ("SSL_HTTPS" for instance), configure it via the $trustedHeaderSet
 * argument of the Request::setTrustedProxies() method instead.
 *
 * @return bool
 */
public function isSecure()
{
    …… 重点看注释
}

如果使用了教程中的默认设置,最终返回的链接是否启用 https:// 是由服务器的相关配置决定的。 herokuapp.com 这个域名是有 SSL 证书的,如果要渲染出 https:// 链接,方法有两个:1.修改 heroku 上的相关配置;2.设定 $forceScheme 的值,强制启用 HTTPS

6年前 评论

这个问题困扰了我几天,解决方案记录一下:

如果你前端用了 SLB 的话,后端默认是 80 端口,需要在 SLB 中设置 X-Forwarded-Proto,同时修改 TrustProxies.php 这个 Middleware 加入相关的前端代理服务器 IP,官网文档参见

https://learnku.com/docs/laravel/6.x/requests#conf...

5年前 评论
堂堂糖唐

最简单的处理方式,修改nginx代理fpm配置:

server {
    listen      80;
    server_name www.a.com;
    root        /www/code;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass    127.0.0.1:9000;
        fastcgi_param   HTTPS on;
        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include         fastcgi_params;
    }
}

注意fastcgi_param HTTPS on;

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!