Laravel 5 how to set Cache-Control HTTP header globally?

后端 未结 3 848
名媛妹妹
名媛妹妹 2020-12-15 23:23

My Laravel application is returning Cache-Control: no-cache, private HTTP header by default for each site. How can I change this behaviour?

P.S.: It is

相关标签:
3条回答
  • 2020-12-15 23:43

    Laravel 5.5 <

    You can have a global middleware for that. something like:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class CacheControl
    {
        public function handle($request, Closure $next)
        {
            $response = $next($request);
    
            $response->header('Cache-Control', 'no-cache, must-revalidate');
            // Or whatever you want it to be:
            // $response->header('Cache-Control', 'max-age=100');
    
            return $response;
        }
    }
    

    then just register this as a global middleware in the Kernel file:

    protected $middleware = [
        ....
        \App\Http\Middleware\CacheControl::class
    ];
    
    0 讨论(0)
  • 2020-12-15 23:43

    Laravel 5.6+

    There's no longer any need to add your own custom middleware.

    The SetCacheHeaders middleware comes out of the box with Laravel, aliased as cache.headers

    The nice thing about this Middleware is that it only applies to GET and HEAD requests - it will not cache POST or PUT requests since you almost never want to do that.

    You can apply this globally easily by updating your RouteServiceProvider:

    protected function mapWebRoutes()
    {
        Route::middleware('web')
            ->middleware('cache.headers:private;max_age=3600') // added this line
            ->namespace($this->namespace)
            ->group(base_path('routes/web.php'));
    }
    
    protected function mapApiRoutes()
    {
        Route::prefix('api')
            ->middleware('api')
            ->middleware('cache.headers:private;max_age=3600') // added this line
            ->namespace($this->namespace)
            ->group(base_path('routes/api.php'));
    }
    

    I don't recommend that though. Instead, as with any middleware, you can easily apply to specific endpoints, groups, or within the controller itself, e.g.:

    Route::middleware('cache.headers:private;max_age=3600')->group(function() {
        Route::get('cache-for-an-hour', 'MyController@cachedMethod');
    });
    

    Note that the options are separated by semicolon not comma, and hyphens are replaced by underscores. Also, Symfony only supports a limited number of options:

    'etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public', 'immutable'

    In other words you can't simply copy and paste a standard Cache-Control header value, you will need to update the formatting:

    CacheControl format:       private, no-cache, max-age=3600
      ->
    Laravel/Symfony format:    private;max_age=3600
    
    0 讨论(0)
  • 2020-12-15 23:55

    For people that seek a way to write less code, here is another way you can add headers to a response without extra steps.

    In the example above, I created a middleware to prevent routes from being cached in the end user browser.

    <?php
    
    class DisableRouteCache
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            return $next($request)->withHeaders([
                "Pragma" => "no-cache",
                "Expires" => "Fri, 01 Jan 1990 00:00:00 GMT",
                "Cache-Control" => "no-cache, must-revalidate, no-store, max-age=0, private",
            ]);
        }
    }
    

    Source: Attaching Headers To Responses

    0 讨论(0)
提交回复
热议问题