proxy_intercept_errors 是拦截开关,必须与同作用域的 error_page 配合使用;仅启用该指令但未配置对应 error_page 时无效,且仅对状态码 ≥400、响应体非空的合法 HTTP 响应生效。

要让 Nginx 代理正确处理后端返回的特殊状态码(比如 404、500、503 等),关键不是“拦截后改写”,而是控制 Nginx 是否将这些状态透传给客户端,或是否交由自定义页面/逻辑处理。默认情况下,Nginx 会原样转发大多数响应状态,但对部分错误码有默认行为,且需显式配置才能触发干预。
启用后端错误状态拦截
Nginx 默认不处理后端返回的 4xx/5xx 响应——它直接透传给用户。若想用自定义页面(如统一错误页)或执行额外动作(如调用通知脚本),必须开启 proxy_intercept_errors:
- 在对应 location 或 server 块中添加:proxy_intercept_errors on;
- 该指令仅对 400 及以上状态生效,且要求后端响应体长度 ≥ 512 字节(否则可能绕过拦截)
- 搭配 error_page 指令使用,例如:error_page 500 502 503 504 /err50x.html;
区分透传与重试的适用场景
注意:状态码处理和重试是两套机制,不能混用。
- 透传:后端返回 503,Nginx 直接发给浏览器——适合你希望前端真实感知服务不可用
- 拦截+自定义:后端返回 503,Nginx 拦截并返回静态维护页——适合用户体验兜底
- 重试:后端返回 503 且配置了 proxy_next_upstream http_503,Nginx 才会换节点重发请求——这属于容错,不是状态处理
保留原始状态但补充响应头
有时你既不想拦截,又需要标记来源(比如告诉前端“这是后端报的 503”),可配合 add_header 和变量:
- add_header X-Backend-Status $upstream_http_status; —— 将上游实际状态写入响应头
- add_header X-Backend-Time $upstream_response_time; —— 同时附带后端耗时,便于排查
- 注意:这些头仅在成功收到后端响应后才可用;若连接失败或超时,$upstream_http_status 为空
对特定状态做条件响应
借助 map 指令可实现更灵活的状态路由,比如将所有后端 401 重定向到登录页:
- 在 http 块中定义:map $upstream_http_status $redirect_to_login { 401 1; default 0; }
- 在 location 中:if ($redirect_to_login) { return 302 https://login.example.com?from=$request_uri; }
- 注意:if 在 location 中慎用,优先考虑 error_page + 内部重定向方案


















