Load Blade Assets with Https in Laravel

Load Blade assets with https in Laravel

I had a problem with asset function when it's loaded resources through HTTP protocol when the website was using HTTPS, which is caused the "Mixed content" problem.

To fix that you need to add \URL::forceScheme('https') into your AppServiceProvider file.

So mine looks like this (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()
{
//
}
}

This is helpful when you need https only on server (config('app.env') === 'production') and not locally, so don't need to force asset function to use https.

Laravel not using https for assets and dynamic routes

The asset() helper relies on a couple possibilities to determine whether to make a HTTP or HTTPS URL:

  • $_SERVER['HTTPS'] being on. This is Apache's way of doing things. For nginx, you can set that server param yourself in the config.
  • $_SERVER['HTTP_X_FORWARDED_PROTO'] being https.

If you're behind a load balancer, it's probably sending the X-Forwarded-Proto header, but Laravel doesn't trust it by default because it can be set by a malicious user in some cases. You can tell Laravel to trust this header coming from your load balancer using the TrustedProxy package. (edit: This is now built into Laravel)

See also: Symfony2: getScheme does not return 'https' (Laravel uses Symfony's getScheme() function for this)

laravel asset() method doesn't return https

As you can see from GitHub the asset method is calling getScheme to determine what the scheme should be.

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;
}

So if you don't provide the asset 2nd parameter $secure then it uses the request scheme. Otherwise you can provide $secure to force the desired scheme regardless of what is the scheme in the request.

If you look at the code you'll see that if $secure is null and no cache is set than the cache is set to the request scheme (i.e. $this->request->getScheme()) and therefore returned.

Laravel include css file from Mixed Content

I think the solution is to force https in production :

<?php

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\URL;

class AppServiceProvider extends ServiceProvider
{
public function boot()
{
if($this->app->environment('production')) {
URL::forceScheme('https');
}
}
}

another solution is to use ASSET_URL :

.env

ASSET_URL=https://example.com

.env.local

ASSET_URL=http://local.example.com

Switching Laravel assets between http and https in local and production

instead of manually setting it through configs you could use Request::secure() to check, if the request is done over HTTPS.

reference: laravel request information

Add Public to asset path in Laravel

Before Laravel 5.7.14

Take a look at Illuminate\Routing\UrlGenerator class and its asset($path, $secure = null) method. This class is being put to container by url key. What you can do is:

  1. Add your own class, extending UrlGenerator;
  2. Add asset($path, $secure = null) method to your own class, making it return whatever you need;
  3. Create a service provider and register it in config/app.php;
  4. In your service provider's register() method, bind your new class
    to the container by url key.

This way, you don't touch core files at all and your Laravel application is still update friendly.

Update for Laravel 5.7.14 and later

As other answers state, there is the ASSET_URL .env option, which makes it much easier to change the public path. Laravel introduced it in Laravel 5.7.14, which was released about 3 years after my original answer.

Loading assets from *.blade.php in Laravel

You can directly put js/CSS into your public folder if they don't require compiling first (which is in your case) - There is no harm in that

But if you want to go as per recommendation:

  • Pull library using NPM,

  • Add js/CSS into gulpfile.js which you want to copy to the public folder:

    elixir((mix) => {

    mix.sass('app.scss')
    .webpack('app.js')
    .mix.copy('node_modules/foo/bar.css', 'public/css/bar.css');

    });

    https://laravel.com/docs/5.4/mix#copying-files-and-directories

  • Run npm run command

  • And then include into your blade view like:

    <link href="{{ asset('css/bar.css') }}" rel="stylesheet">

Laravel 8 – use blade asset to display image, but loading from resources subfolder

I managed to do what I wanted for this one. All credit for @donkarnash on this question that I posted for the worst case scenario for creating a route alias for it: Laravel 8 – create route alias for image folder inside public directory

I used the symbolic link approach, almost similar to what @sergey-ligus had mentioned in the comments.

1 – edit laravel \config\filesystems.php file:
Originally, looks like this:

links' => [
public_path('storage') => storage_path('app/public'),
],

After I edited, looked like this:

'links' => [
public_path('storage') => storage_path('app/public'),
public_path('files-layout') => resource_path('app_files_layout'),
],

2 - Then, in the command terminal, I executed the following command:

php artisan storage:link

3 - Finally, I ran the server and tested out. Not only could I access the file in the browser via: http://localhost:8000/files-layout/backend-layout-header-tb02-03.jpg, but also could still use laravel asset blade helper.

Blade file:

{{ asset('/files-layout/backend-layout-header-tb02-03.jpg') }}


Related Topics



Leave a reply



Submit