【问题标题】:Load Blade assets with https in Laravel在 Laravel 中使用 https 加载 Blade 资源
【发布时间】:2016-03-26 11:47:10
【问题描述】:

我正在使用这种格式加载我的 css: <link href="{{ asset('assets/mdi/css/materialdesignicons.min.css') }}" media="all" rel="stylesheet" type="text/css" /> 并且它可以很好地加载所有 http 请求

但是当我使用 SSL (https) 加载我的登录页面时,我得到一个 ...page... was loaded over HTTPS, but requested an insecure stylesheet 'http...

谁能告诉我如何通过 https 而不是 http 制作刀片加载资产?

我应该尝试安全地加载资产吗?或者这不是 Blade 的工作?

【问题讨论】:

  • 我知道已经有好几年了,但我建议取消将我的答案标记为已接受的答案并选择Scofield's Answer 作为正确答案。他的比我的更有用、更灵活,这是一个相当高质量的问题,人们正在自己有机地发现。

标签: php laravel http https laravel-blade


【解决方案1】:

我的asset函数在网站使用HTTPS时通过HTTP协议加载资源时出现问题,导致“混合内容”问题。

要解决此问题,您需要将 \URL::forceScheme('https') 添加到您的 AppServiceProvider 文件中。

所以我的看起来像这样(Laravel 5.4):

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        if(config('app.env') === 'production') {
            \URL::forceScheme('https');
        }
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

当您仅在服务器 (config('app.env') === 'production') 上而不是本地需要 https 时,这很有帮助,因此不需要强制 asset 函数使用 https。

【讨论】:

  • 这是一个更好的答案,因为我只想在生产服务器上使用 https
  • 同意。虽然我的回答可能直接解决了这个问题,但在您有多个环境可能会或可能不会通过 HTTPS 提供服务的情况下,这种方法可能会更好。
  • 仅在生产上更有意义并适合我的情况。
  • 我使用了同样的模式,但我没有只检查“app.env”,而是查看了“app.url”。如果它以“https”开头,那么我会强制执行该方案。
  • 这不再是正确的做法。您应该使用 TrustProxies 中间件...
【解决方案2】:

我相信secure_asset 就是您要找的。​​p>

<link href="{{ secure_asset('assets/mdi/css/materialdesignicons.min.css') }}" media="all" rel="stylesheet" type="text/css" />

2018 年 5 月 15 日编辑: 虽然我的回答直接解决了这个问题,但考虑到 Laravel 现在可以做什么,这有点过时了;在某些情况下,您可能希望在某些环境中强制使用 HTTPS,但在其他环境中不强制使用。

See Scofield's answer below 以获得更灵活的解决方案来应对此类情况。

2020 年 8 月 11 日编辑: 说真的,Scofield's Answer 比我的更好,将为不同的环境提供更大的灵活性。给他你的updoots。

【讨论】:

  • 如果你在本地机器上使用虚拟主机,这将不起作用,从资产更改为安全资产,你应该更新你的 AppServiceProvider->boot 函数`` $url->forceScheme(' https'); ``` 你也可以像这样把它放在 if 条件中 ``` if (env('APP_ENV') !== 'local') { $url->forceScheme('https'); } ``` 记得运行命令“php artisan config:clear”。
  • @HiteshKumar 您从哪里听说它“不起作用”?只要您知道如何生成和信任自己的证书,这将在本地计算机上的虚拟主机上正常工作。您还可以查看我两年多前的编辑,指出这个答案不如下面斯科菲尔德的答案那么全面。您对使用 artisan config:clear 的建议也是多余的,在这种情况下没有任何作用,因为我或 Scofield 的方法都没有更改任何配置。
  • 因为我已经尝试过了,并且我建议“artisan config:clear”,因为如果本地和生产环境的条件如此,这将清除 add->config 并加载 .env 变量。这可以在旧版本的 laravel 中工作,但为了防止它改变了。
【解决方案3】:

我使用@Scofield 回答 \URL::forceScheme('https'); 这个解决方案也可以为所有路由显示 https 但这对我不起作用 $request->url() 它显示 http 而不是 https

所以我使用$this-&gt;app['request']-&gt;server-&gt;set('HTTPS', true); 而不是\URL::forceScheme('https');

我正在使用 Laravel 5.4 并更新 .env 文件和 appserviceproviders

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
use Log;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     *
     */
    public function boot()
    {
        If (env('APP_ENV') !== 'local') {
            $this->app['request']->server->set('HTTPS', true);
        }

        Schema::defaultStringLength(191);
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

在我的 env 文件中我已经更改了

APP_ENV=local to APP_ENV=development

APP_ENV=本地的本地 APP_ENV=在工作服务器上的开发/生产

更改环境后运行此工匠命令

php artisan config:clear

希望对你有帮助:-)

【讨论】:

  • @NavaBogatee 很高兴听到这个消息。 :-)
  • config:clear 如果改为使用 env(),则不需要使用 config() 或 $this->app->environment()
【解决方案4】:

有一个环境变量“ASSET_URL”,您可以在其中使用 http 或 https 放置您的应用程序 url

ASSET_URL=https://your.app.url #for production

ASSET_URL=http://your.app.url #for local development

【讨论】:

  • 这应该是公认的答案。为什么要写 10-20 行代码呢?
  • 这是最好的答案!它对我有用
  • 它在 v8.54 中就像一个魅力。这个解决方案要好得多,因为您所要做的就是覆盖 .env 中的默认变量,或者如果它不存在则创建一个。
【解决方案5】:

另一种方法是将true 作为第二个参数传递。

/**
 * Generate an asset path for the application.
 *
 * @param  string  $path
 * @param  bool    $secure
 * @return string
 */
function asset($path, $secure = null)
{
    return app('url')->asset($path, $secure);
}

正如您在下面看到的secure_asset 只需使用第二个参数true 调用asset

/**
 * Generate an asset path for the application.
 *
 * @param  string  $path
 * @return string
 */
function secure_asset($path)
{
    return asset($path, true);
}

【讨论】:

  • 感谢您的替代建议 :)
【解决方案6】:

判断当前的Request 是否安全不应由您决定。底层 Symfony\Component\HttpFoundation\Request 具有 Laravel 内部使用的 isSecure 方法。

public function isSecure()
{
    if ($this->isFromTrustedProxy() && $proto = $this->getTrustedValues(self::HEADER_X_FORWARDED_PROTO)) {
        return \in_array(strtolower($proto[0]), array('https', 'on', 'ssl', '1'), true);
    }

    $https = $this->server->get('HTTPS');

    return !empty($https) && 'off' !== strtolower($https);
}

因此,如果您的服务器没有通过 On 传递 HTTPS 标头,它应该传递 X-FORWARDED-PROTO 并且必须由您的 TrustProxies 中间件允许。

如果您使用反向代理,您应该找出您的代理传递 IP - 您可以通过获取 $_SERVER['REMOTE_ADDR'] 变量并将 IP 设置为您的 TrustProxies 中间件轻松做到这一点:

/**
 * The trusted proxies for this application.
 *
 * @var array
 */
protected $proxies = [
    '123.123.123.123',
];

Laravel (Symfony) 会自动检测Request 是否安全并相应地选择协议。

【讨论】:

    【解决方案7】:

    问题是我本地机器上的 cloudflare 工作正常,但在线服务器不是解决方案

     public function boot()
        {
    
            if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&  $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
                 \URL::forceScheme('https');
            }
        }
    

    【讨论】:

      【解决方案8】:

      这是使 HTTPS 与资产一起使用的配置。要在生产环境中启用此功能,请在 .env 文件中添加 REDIRECT_HTTPS=true。

      <?php
      
      namespace App\Providers;
      
      use Illuminate\Support\ServiceProvider;
      use Illuminate\Support\Facades\Schema;
      
      class AppServiceProvider extends ServiceProvider
      {
          /**
           * Bootstrap any application services.
           *
           * @return void
           */
          public function boot()
          {
              if(env('REDIRECT_HTTPS'))
              {
                  \URL::forceScheme('https');
              }
      
              Schema::defaultStringLength(191);
          }
      
          /**
           * Register any application services.
           *
           * @return void
           */
          public function register()
          {
              //
          }
      }
      

      【讨论】:

        【解决方案9】:

        我最终把它放在了我的刀片文件中:

        @if(parse_url(url('/'), PHP_URL_SCHEME) == 'HTTPS')
            <link rel="stylesheet" href="{{ secure_asset('assets/css/slider.css') }}">
            <link rel="stylesheet" href="{{ secure_asset('assets/css/dropdown.css') }}">
        @else
            <link rel="stylesheet" href="{{ asset('assets/css/slider.css') }}">
            <link rel="stylesheet" href="{{ asset('assets/css/dropdown.css') }}">
        @endif
        

        【讨论】:

          【解决方案10】:

          在将 Laravel 版本从 5.4 升级到 5.5 时,我遇到了同样的问题。

          只需在 app/Providers/AppServiceProvider.php 中添加\URL::forceScheme('https');。它奏效了。

          <?php
          
          namespace App\Providers;
          
          use Illuminate\Support\ServiceProvider;
          use Illuminate\Support\Facades\Schema;
          
          class AppServiceProvider extends ServiceProvider
          {
              /**
               * Bootstrap any application services.
               *
               * @return void
               *
               */
              public function boot()
              {
                  \URL::forceScheme('https');
              }
          ...
          

          【讨论】:

            【解决方案11】:

            在 .env 文件中,请将本地值更改为生产

            APP_ENV=production
            

            【讨论】:

              猜你喜欢
              • 2022-01-21
              • 1970-01-01
              • 2023-03-31
              • 1970-01-01
              • 1970-01-01
              • 2014-09-06
              • 2021-10-23
              • 2020-07-28
              • 2016-09-21
              相关资源
              最近更新 更多