Is it possible to add cdn.mydomain.com/assets in Laravel asset() function?

Viewed 343

I want the asset of my site to be loaded as cdn.mydomain.com/asset_path instead of mydomain.com/asset path.

without using any cloud CDN.

In short I want this <img src="{{asset('/js/app.js')}}" > =<img src="mydomain.com/js/app.js" >

to be in this form

<img src="{{asset('/js/app.js')}}" > =<img src="cdn.mydomain.com/js/app.js" >

Please have a look at this package as well this is doing the same but not supported for laravel 8 https://github.com/damianromanowski/simplecdn

Any help will be appreciated. Thanks in advance

Note: I am using Laravel 8

2 Answers

You can configure the asset URL host by setting the ASSET_URL variable in your .env file. This can be useful if you host your assets on an external service like Amazon S3 or another CDN:

// ASSET_URL=http://cdn.mydomain.com

$url = asset('js/app.js'); // http://cdn.mydomain.com/js/app.js

See https://laravel.com/docs/8.x/helpers#method-asset

I solve it myself by adding middleware and changing the response sent to the browser.

Inspired by Above mentioned package.

<?PHP

  namespace App\Http\Middleware;

  use Closure;
  use Illuminate\Http\Request;

 class CdnMiddleware
 {
/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle(Request $request, Closure $next)
{
    $response = $next($request);
    $output = $response->getOriginalContent();
    $rules = array(

        array(
            // 'url'        => array('http://images.example.com/', 'http://images2.example.com/'),
            // 'remove' => 'assets/images/',
            'pattern'   => 'png|tif|tiff|gif|jpeg|jpg|jif|jfif|jp2|jpx|j2k|j2c|ico',
            'enabled'   => true
        ),
        
        array(
            'pattern'   => 'css',
            'enabled'   => true
        ),
        
        array(
            'pattern'   => 'js',
            'enabled'   => true
        ),
        
        array(
            'pattern'   => 'asf|avi|flv|m1v|m2v|m4v|mkv|mpeg|mpg|mpe|ogg|rm|wmv|mp4|webm',
            'enabled'   => true
        )
        
        );
        $url =  array(

            'http://cdn.my-domain.com/'
    
        );
    if (is_string($output) || method_exists($output, '__toString')) {
        $urls = preg_match_all("#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|[^[:punct:]\s]|/)#", $output, $matches);

        foreach ($matches[0] as $uri)
            foreach ($rules as $group)
                if (@$group['enabled'] && preg_match('/\.(' . @$group['pattern'] . ')(?:[\?\#].*)?$/i', $uri, $matchess))
                {
                    $config_url = $url;

                    $config_remove = '';
                    $main_url = \URL::to('/');
                    $asset_path = str_replace(str_finish(strval($main_url), '/'), '', $uri);

                    // check for external URLs. so far all the urls with current hostname
                    // has been removed. If there is a still URL which has http://---- that means
                    // its an external URL
                    $extMatch = [];
                    $extUrl = preg_match("#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|[^[:punct:]\s]|/)#", $asset_path, $extMatch );

                    if(isset($extMatch[0]))
                        continue;

                    if (isset($group['url']))
                        $config_url = $group['url'];

                    if (isset($group['remove']))
                        $config_remove = $group['remove'];

                    if ($config_remove)
                        $asset_path = str_replace(str_finish($config_remove, '/'), '', $asset_path);

                    $cdn_url = is_array($config_url) ? $config_url[array_rand($config_url)] : $config_url;
                    $output = str_replace($uri, str_finish($cdn_url, '/') . $asset_path, $output);
                }

        $response->setContent($output);
    }
    //dd($response->getOriginalContent());
    return $response;
}

}

Related