Laravel 5.5如何全局设置Cache-Control HTTP标头

时间:2018-08-13 11:42:15

标签: php laravel http laravel-5 http-headers

我的Laravel应用程序默认为每个站点返回Cache-Control: no-cache, private HTTP标头。我该如何改变这种行为?

P.S .:这不是PHP.ini的问题,因为将session.cache_limiter更改为空/公共不会改变任何内容。

3 个答案:

答案 0 :(得分:5)

您可以为此使用全局中间件。像这样:

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

然后将其注册为内核文件中的全局中间件:

protected $middleware = [
    ....
    \App\Http\Middleware\CacheControl::class
];

答案 1 :(得分:2)

对于寻求减少代码编写方式的人们来说,这是另一种无需额外步骤即可将标题添加到响应的方法。

在上面的示例中,我创建了一个中间件,以防止路由被缓存在最终用户浏览器中。

<?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",
        ]);
    }
}

来源:Attaching Headers To Responses

答案 2 :(得分:1)

Laravel 5.6 +

不再需要添加自己的自定义中间件。

SetCacheHeaders中间件与Laravel开箱即用,别名为cache.headers

关于此中间件的好处是它仅适用于GETHEAD请求-不会缓存POSTPUT请求,因为您几乎从不愿意做到这一点。

您可以通过更新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'));
}

但是我不建议这样做。相反,与任何中间件一样,您可以轻松地将其应用于特定的端点,组或在控制器本身内,例如:

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

请注意,选项之间用分号而不是逗号分隔,并且将连字符替换为下划线。此外,Symfony仅支持a limited number of options

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

换句话说,您不能简单地复制并粘贴标准的Cache-Control标头值,则需要更新格式:

CacheControl format:       private, no-cache, max-age=3600
  ->
Laravel/Symfony format:    private;max_age=3600