You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中强制设置缓存响应头?

Laravel缓存响应头在Nginx生产环境冲突的解决方法

问题背景

我在Laravel里配置了路由,同时用cache.headers中间件和手动设置响应头,目的是让文件能在客户端缓存,避免重复请求。本地环境一切正常,但部署到Nginx生产环境后,响应头出现冲突——同时存在允许缓存和禁止缓存的头信息,导致缓存失效。

路由配置

Route::group([
    'middleware' => ['cache.headers:public;max_age=600'],
], function () {
    Route::get('/my-file', function ($locale) {
        //some logic

        $contents = 'my file content';
        $response = \Response::make($contents, 200);

        $response->header('Cache-Control', 'public, max-age=600');
        $response->header('Expires', now()->addSeconds(600)->toRfc7231String());
        $response->header('Content-Type', 'application/javascript');
        $response->header('Pragma', '');

        return $response;
    });
});

本地正常响应头

Cache-Control:
max-age=600, public
Connection:
close
Content-Type:
application/javascript
Date:
Thu, 08 Feb 2024 19:23:55 GMT, Thu, 08 Feb 2024 19:23:55 GMT
Expires:
Thu, 08 Feb 2024 19:33:55 GMT
Host:
127.0.0.1:8000
Pragma:

生产环境冲突响应头

Cache-Control:
no-store, no-cache, must-revalidate
Cache-Control:
max-age=600, public
Connection:
keep-alive
Content-Encoding:
gzip
Content-Type:
application/javascript; charset=utf-8
Date:
Thu, 08 Feb 2024 19:17:21 GMT
Expires:
Thu, 19 Nov 1981 08:52:00 GMT
Expires:
Thu, 08 Feb 2024 19:27:21 GMT
Pragma:
no-cache
Pragma:
Server:
nginx/1.14.0 (Ubuntu)

解决步骤

1. 移除重复的缓存头设置

你同时用了Laravel的缓存中间件和手动设置响应头,这会导致重复输出Cache-Control和Expires。二选一即可,推荐保留中间件简化代码:

Route::group([
    'middleware' => ['cache.headers:public;max_age=600;etag'],
], function () {
    Route::get('/my-file', function ($locale) {
        //some logic

        $contents = 'my file content';
        $response = \Response::make($contents, 200);

        $response->header('Content-Type', 'application/javascript');
        $response->header('Pragma', '');

        return $response;
    });
});

2. 修正Nginx配置,覆盖默认禁止缓存的头

冲突的核心是Nginx默认添加了禁止缓存的头(比如no-store, no-cache, must-revalidate和旧的Expires),需要在对应location块中强制覆盖:

如果是反向代理Laravel的配置

location /my-file {
    # 设置正确的缓存头,always确保在所有响应中都添加
    expires 600s;
    add_header Cache-Control "public, max-age=600" always;
    add_header Expires $date_gmt;
    add_header Pragma "";

    # 代理到Laravel应用
    proxy_pass http://your-laravel-upstream; # 替换成你的Laravel地址,比如127.0.0.1:9000
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # 保留gzip配置(如果需要)
    gzip on;
    gzip_types application/javascript;
}

如果是FastCGI配置(比如php-fpm)

location /my-file {
    expires 600s;
    add_header Cache-Control "public, max-age=600" always;
    add_header Expires $date_gmt;
    add_header Pragma "";

    # 禁止fastcgi根据Pragma头禁用缓存
    fastcgi_cache_bypass "";
    fastcgi_no_cache "";

    # 其他fastcgi配置
    fastcgi_pass unix:/run/php/php7.4-fpm.sock; # 替换成你的php-fpm路径
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

3. 验证并重启Nginx

修改配置后先验证语法是否正确:

nginx -t

验证通过后重启Nginx:

systemctl restart nginx

4. 测试响应头

再次请求/my-file,检查响应头是否只有一组正确的缓存配置,确保没有冲突的头信息。

内容的提问来源于stack exchange,提问作者iamx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 09:53:22