Search code examples
phpcsslaravelfile-uploadhelper

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


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


Solution

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

    }