我的设置:

  • Mac OSX 上的 Homestead,配置了多个站点
  • 我有一个站点设置,使用 domfit.test 作为本地域(使用 hostsupdater 自动映射)

  • 我的问题:

    如果我vagrant ssh,然后share domfit.test我得到一个随机生成的URL ngrok正如你所期望(http://whatever.ngrok.io),但是当我所有访问该网址我的资源/途径被前缀http://domfit.test/(http://domfit.test/login例如)

    我尝试了以下方法:
  • 设置 APP_URL 作为 ngrok URL
  • php artisan config:clear
  • php artisan cache:clear
  • {{ url('login') }}
  • {{ route('login') }}

  • 我的理解是 url() 应该返回浏览器请求的实际 URL(而不是使用 APP_URL )但它总是返回 domfit.test

    如果我将我的站点重命名为 Homestead.yaml(例如到 newdomfit.test )并重新配置,那么这就是 url()route() 使用的域,不管 135135131341 使用 0x251812231343143。所以 APP_URL 似乎在强制那个域。这就引出了一个问题——你打算如何实际使用共享功能?

    我是 Laravel 的新手,所以我不确定所有这些是否都是预期的行为,我误解了什么?

    我只希望模板中的链接和资源适用于本地( Homestead.yaml )、共享( domfit.test )并最终使用相同的代码段进行生产。我担心的是,当我试图让这个网站上线时,我将不得不更改我所有的 ngrokroute() 引用。

    在下面编辑

    好的,我刚刚又试了一次。将 url() 更改为 APP_URL :

    在我的整个代码库中搜索 ngrok ,只有一些随机 session 文件似乎有引用:

    代码/domfit/存储/框架/ session /
    APP_NAME=DomFit
    APP_VERSION=0.01
    APP_ENV=local
    APP_KEY=XXXX
    APP_DEBUG=true
    APP_URL=http://04b7beec.ngrok.io
    

    然后在我的 Controller 中,我让它做一些简单的调试:
    echo(url('/login'));
    echo(route('login'));
    echo($_SERVER['HTTP_HOST']);
    echo($_SERVER['HTTP_X_ORIGINAL_HOST']);
    

    如果我使用 domfit.test URL,我得到的输出是:
    http://domfit.test/login
    http://domfit.test/login
    domfit.test
    04b7beec.ngrok.io
    

    我不明白 ngrok 如何返回错误的网址?

    看起来可能与此有关:https://github.com/laravel/valet/issues/342

    另一个编辑

    看起来它与 Homestead 的 $_SERVER['HTTP_HOST'] 命令有关:
    function share() {
    if [[ "$1" ]]
    then
        ngrok http ${@:2} -host-header="$1" 80
    else
        echo "Error: missing required parameters."
        echo "Usage: "
        echo "  share domain"
        echo "Invocation with extra params passed directly to ngrok"
        echo "  share domain -region=eu -subdomain=test1234"
    fi
    

    }

    根据他们的文档,将选项 share 传递给 -host-header :



    如果我在没有它的情况下使用 ngrok,那么显示的网站是一个不同的网站(因为我在 Homestead 中配置了多个网站) - 所以我仍然不确定如何解决这个问题。暂时我可以禁用其他站点,因为我没有积极开发这些站点。

    最佳答案

    即使您要访问 ngrok url,请求中的主机 header 仍设置为您站点的名称。 Laravel 使用主机头来构建链接、 Assets 等的绝对 url。ngrok 在 X-Original-Host 头中包含 ngrok url,但 Laravel 对此一无所知。

    该问题有两种基本解决方案:

  • 使用正确的服务器和 header 值更新请求,或
  • 使用 forceRootUrl() 方法忽略服务器和 header 值。


  • TrustedProxy 和转发主机

    如果您使用 TrustedProxies(Laravel 中的默认设置 >= 5.5),并且您已将其配置为信任所有代理( protected $proxies = '*'; ),您可以将 X-Forwarded-Host header 设置为 0x25181223113431 header 。然后 Laravel 将使用 X-Original-Host header 中的值来构建所有绝对 url。

    您可以在 Web 服务器级别执行此操作。例如,如果您使用 apache,则可以将其添加到 X-Forwarded-Host 文件中:
    # Handle ngrok X-Original-Host Header
    RewriteCond %{HTTP:X-Original-Host} \.ngrok\.io$ [NC]
    RewriteRule .* - [E=HTTP_X_FORWARDED_HOST:%{HTTP:X-Original-Host}]
    

    如果您更喜欢在您的应用程序而不是 Web 服务器中处理此问题,您将需要更新 Laravel 请求。有很多地方你可以选择这样做,但一个例子是你的 public/.htaccess 方法:
    public function boot(\Illuminate\Http\Request $request)
    {
        if ($request->server->has('HTTP_X_ORIGINAL_HOST')) {
            $request->server->set('HTTP_X_FORWARDED_HOST', $request->server->get('HTTP_X_ORIGINAL_HOST'));
            $request->headers->set('X_FORWARDED_HOST', $request->server->get('HTTP_X_ORIGINAL_HOST'));
        }
    }
    

    不使用 TrustedProxies

    如果您不使用 TrustedProxies,则不能使用 AppServiceProvider::boot() 方法。但是,您仍然可以更新应用程序中的服务器和 header 值。在这种情况下,您需要覆盖 Host header :
    public function boot(\Illuminate\Http\Request $request)
    {
        if ($request->server->has('HTTP_X_ORIGINAL_HOST')) {
            $request->server->set('HTTP_HOST', $request->server->get('HTTP_X_ORIGINAL_HOST'));
            $request->headers->set('HOST', $request->server->get('HTTP_X_ORIGINAL_HOST'));
        }
    }
    

    使用 .htaccess

    如果您不想修改任何 header 或 Laravel 请求,您可以简单地告诉 URL 生成器使用哪个根 url。 URL 生成器有一个 forceRootUrl() 方法,您可以使用它告诉它使用特定值而不是查看请求。同样,在您的 forceRootUrl() 方法中:
    public function boot(\Illuminate\Http\Request $request)
    {
        if ($request->server->has('HTTP_X_ORIGINAL_HOST')) {
            $this->app['url']->forceRootUrl($request->server->get('HTTP_X_FORWARDED_PROTO').'://'.$request->server->get('HTTP_X_ORIGINAL_HOST'));
        }
    }
    

    关于Laravel 和 ngrok : url domain is not correct for routes and assets,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50194923/

    10-14 15:58
    查看更多