Laravel 9静态资源高效缓存策略配置无效问题排查
Laravel 9 + Apache2 静态资源缓存策略失效排查与解决
问题场景
在部署于Apache2服务器的Laravel 9项目中配置静态资源高效缓存策略,已在.htaccess文件中添加启用浏览器缓存的代码:
<IfModule mod_expires.c> ExpiresActive On # Images ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/gif "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/webp "access plus 1 year" ExpiresByType image/svg+xml "access plus 1 year" ExpiresByType image/x-icon "access plus 1 year" # Video ExpiresByType video/webm "access plus 1 year" ExpiresByType video/mp4 "access plus 1 year" ExpiresByType video/mpeg "access plus 1 year" # Fonts ExpiresByType font/ttf "access plus 1 year" ExpiresByType font/otf "access plus 1 year" ExpiresByType font/woff "access plus 1 year" ExpiresByType font/woff2 "access plus 1 year" ExpiresByType application/font-woff "access plus 1 year" # CSS, JavaScript ExpiresByType text/css "access plus 1 year" ExpiresByType text/javascript "access plus 1 year" ExpiresByType application/javascript "access plus 1 year" # Others ExpiresByType application/pdf "access plus 1 year" ExpiresByType image/vnd.microsoft.icon "access plus 1 year" </IfModule>
同时补充了以下规则:
<filesMatch ".(jpg|jpeg|png|gif|ico|svg|ttf|eot|woff|woff2)$"> Header set Cache-Control "max-age=31536000, public" </filesMatch>
但Lighthouse和Google搜索洞察仍提示「无法为静态资源提供高效缓存策略」,静态资源的HTTP响应头显示:
cache-control: no-cache, private cf-cache-status: MISS cf-ray: 7b4367722899850d-BOM content-encoding: gzip content-type: text/html; charset=UTF-8 date: Fri, 07 Apr 2023 15:46:35 GMT last-modified: Fri, 07 Apr 2023 15:46:34 GMT server: cloudflare set-cookie: XSRF-TOKEN=eyJpdiI6IjZLWldVc1JteUdFTkhZeVJYbU5wemc9PSIsInZhbHVlIjoiVXJMR241MjYrK3pRM0tZeDFDUWpqU0ZVcnVneHZYdUg1REo2U3hqZnhkSmsyK2piRC96dEdzQ1B1WTNKeG5VL2E5Z0Z5eHYycEhRUHFlNzliRithamQvVU9GWmpmSEVOQS9hM1FrTCsyZjVZOGplbTdzQWVzMUg4YkRGNWVzWC8iLCJtYWMiOiI4MjQwY2VjZmFkNjQzOTY1OTZmNzliNjNhZDdiYTRjMTYyNGRlNTdkZDQ0MmY4OGMxOGYwODg4ZDgwNjEzODkxIiwidGFnIjoiIn0%3D; expires=Fri, 07-Apr-2023 17:46:34 GMT; Max-Age=7200; path=/ set-cookie: phprank_session=eyJpdiI6Iks2ekpzdFhsRy9FRCs4UFBSdU5OR2c9PSIsInZhbHVlIjoiS2M0WGNwVzE1VS9YTkE4SUxFUVM1SXY1bmNEbWV5d1BJcTBZRVBzU3NlVFkzdEpBOTZTMFhDeXlRcmtxa0s3OWFwZzV2amIvY1NSZ2E0cVRxNkJsNEdPQWxSUTNrWnEvTnBUSitGRGRHTUhIREVIM2wrVmJQSkRieDBlZzdORkwiLCJtYWMiOiI4YjNhODJjZTVlYTJmOGMyMDA5OTcwZDM2NDY5N2I3NmU1MjQ1NjkzMjBlZjI5ODEzZTg2MWZhNzQzOWY5YmIxIiwidGFnIjoiIn0%3D; expires=Fri, 07-Apr-2023 17:46:34 GMT; Max-Age=7200; path=/; httponly vary: Accept-Encoding,User-Agent
原因分析
从响应头可见cache-control: no-cache, private,这是Laravel的默认响应头,它覆盖了.htaccess中的缓存设置。核心原因有两个:
- 静态资源请求被Laravel路由接管,没有直接由Apache处理,导致Laravel默认的缓存头被添加到静态资源响应中;
- 配合Cloudflare使用时,缓存规则可能冲突,导致源服务器的缓存设置未生效。
解决步骤
1. 让静态资源直接由Apache处理
修改项目根目录(或public目录)的.htaccess,优先处理静态资源,跳过Laravel路由:
RewriteEngine On # 静态资源直接返回,不经过Laravel RewriteRule ^(css|js|images|fonts)/(.*)$ - [L] # Laravel原有重写规则 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^ index.php [L]
2. 确认Apache模块已启用
确保mod_expires和mod_headers模块开启,执行命令:
sudo a2enmod expires headers sudo systemctl restart apache2
3. 调整Cloudflare缓存规则
在Cloudflare控制台中,设置静态资源的缓存策略为遵循源服务器的缓存头,或直接配置静态资源缓存时间为1年,避免Cloudflare覆盖源服务器的设置。
4. 验证缓存效果
修改完成后,通过浏览器开发者工具查看静态资源的响应头,确认Cache-Control为max-age=31536000, public,同时Expires头显示为1年后的日期。
内容的提问来源于stack exchange,提问作者JustAG33K
相关产品推荐
相关产品推荐

