我最近在切换到 Cloudflare 后遇到了一个问题,解决方案基本上是阻止 Cloudflare 缓存 404 响应。
在我们的负载平衡多服务器设置中,偶尔会出现 404 错误,但 rsync(通过 lsyncd)可以快速修复。在使用 Cloudflare 之前,由于 rsync 可以完成工作,因此对 404 错误的文件的重新请求很快就会变成 200。
但是,由于 Cloudflare 根据缓存标头缓存所有数据,并且 apache 和 nginx 都不会为 404 发送无缓存标头,因此 Cloudflare 最终会暂时缓存 404 响应。
我一直在寻找一种解决方案,在 apache 和 nginx 中全局添加这样的 404 标头(全局,针对所有托管域),但到目前为止还没有结果。
有人可以帮忙吗?
谢谢。
答案1
您不能先使用 error_page 指令,然后使用添加的标题单独处理位置吗?
例如在Nginx中:
server {
...
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
add_header Cache-Control "no-cache" always;
}
}
答案2
你也可以这样做:
map $status $cache_header {
default <for_other_codes>;
404 "no-cache";
}
server {
[ ... ]
add_header "Cache-Control" $cache_header always;
}
答案3
在 apache 2.4 中,你可以尝试类似以下操作:
FileETag None
<IfModule mod_headers.c>
Header always set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" "expr=%{REQUEST_STATUS} == 404"
Header always set Expires "Wed, 11 Jan 1984 05:00:00 GMT" "expr=%{REQUEST_STATUS} == 404"
</IfModule>
这always
很重要,因为这是:
您正在向本地生成的非成功(非 2xx)响应(例如重定向)添加标头,在这种情况下,最终响应中仅使用与始终相对应的表。
<FilesMatch>
您说的是所有 404,但为了提供完整的参考,当然将其包装在或中<LocationMatch>
以限制范围可能是有意义的。
我相信这是 apache 2.4 中的新功能,因为使用expr
条件并不在 2.2 版的 mod_headers 文档中。
curl -I [foo]
不使用这个配置进行测试:
HTTP/1.1 404 Not Found
Date: Thu, 24 May 2018 17:44:29 GMT
Server: Apache/2.4.18 (Ubuntu)
Content-Type: text/html; charset=iso-8859-1
curl -I [foo]
使用此配置进行测试:
HTTP/1.1 404 Not Found
Date: Thu, 24 May 2018 17:44:42 GMT
Server: Apache/2.4.18 (Ubuntu)
Cache-Control: max-age=0, no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Content-Type: text/html; charset=iso-8859-1
资料来源:
答案4
我对这个问题的看法 -
在我们的 PHP 项目中,我们有几个 404 页面,所以我决定在 PHP 级别上使用 PHP header() 函数来执行此操作