proxy_intercept_errors仅拦截≥400非空响应并触发error_page重定向,不处理缓存或分级;分级错误页需配合error_page路由与独立location缓存策略实现。

proxy_intercept_errors 本身不处理缓存,也不分级响应——它只是个“拦截开关”,是否接管错误、返回什么内容、是否走缓存,全靠与它同作用域的 error_page 和后续 location 配置共同决定。想实现“错误响应的缓存分级”,关键不是调 proxy_intercept_errors 的参数,而是分层设计 error_page 的路由逻辑,并配合静态资源缓存策略。
明确 proxy_intercept_errors 的职责边界
它只做一件事:当后端返回 ≥400 状态码(如 502/503/504/404)且响应体非空时,阻止透传,转而触发 Nginx 内部重定向到 error_page 指定的 URI。它不生成内容、不控制缓存、不分级、不读取响应头字段。
- 必须和 error_page 出现在同一作用域(location 或 server),单独开启无效
- 对 Nginx 自身生成的错误(如 upstream 全挂导致的 502)同样生效,只要配置了对应 error_page
- 不拦截 3xx 重定向或空响应体错误(需配合 proxy_buffering off 或后端补全 body)
用 error_page + location 实现“分级”错误页路由
所谓“分级”,是指不同错误类型返回不同页面(如 502 显示“服务暂时不可用”,504 显示“请求超时”,404 显示“页面未找到”),并让这些页面各自走适合的缓存策略。
- 在 location 块中按需映射:
error_page 502 /err/502.html;
error_page 504 /err/504.html;
error_page 404 /err/404.html; - 为每个错误路径单独配置 location,控制缓存行为:
location = /err/502.html {
root /usr/share/nginx/html;
internal;
expires 10s; # 短期缓存,适配快速恢复场景
} - 对通用兜底页(如 /err/maintenance.html)可设更长缓存:
location = /err/maintenance.html {
root /usr/share/nginx/html;
internal;
expires 5m;
}
让错误页本身支持条件化缓存(进阶)
如果希望同一错误页(如 /err/fallback.html)在不同故障场景下返回不同内容(比如带服务名、时间戳、健康检查状态),就不能只靠静态文件——需结合 SSI 或 fastcgi_pass 动态生成,再由 Nginx 缓存结果。
- 启用 SSI 并配置动态降级页:
location = /err/fallback.html {
root /usr/share/nginx/html;
internal;
syntax on;
ssi on;
expires 30s;
} - 在 fallback.html 中嵌入变量:
这样每次渲染都带实时上游信息,Nginx 缓存的是带上下文的 HTML 片段 - 注意:SSI 会略微增加 CPU 开销,需权衡实时性与性能
避免缓存干扰错误响应的几个要点
错误页一旦被缓存,就可能掩盖真实故障状态。务必确保缓存策略与业务容错节奏匹配。
- 所有 error_page 指向的 URI 必须加 internal,防止用户绕过代理直访,也避免 CDN 错误缓存
- 不要对 error_page 的响应设置太长的 max-age(尤其 502/504 类瞬时故障),10s–60s 更稳妥
- 若使用 proxy_cache,确认 error_page 路由不落入 cache 区域——默认 location = /xxx 是不参与 proxy_cache 的,但若用了 alias 或 rewrite,需额外验证
- 用 curl -I 验证最终响应头:确保返回的是你期望的状态码(如 =200 /err/502.html)和 Cache-Control 值











