nginx反向代理接管50x错误需启用proxy_intercept_errors on并限定在proxy_pass所在location,配对error_page指向internal的静态页,确保后端真实返回50x状态码。

要让 Nginx 在反向代理层真正接管 50x 错误(如 502、503、504),关键不是只打开开关,而是构建一个“拦截—匹配—响应”的闭环。proxy_intercept_errors 本身只是个触发器,必须和 error_page、静态资源路径、作用域控制三者严丝合缝配合,才能把后端崩掉时的裸错误变成可控的降级体验。
必须开启并限定作用域
proxy_intercept_errors 默认是 off,不写就等于没配。它只对含 proxy_pass 的 location 生效,不能靠 http 块全局继承:
- 在具体代理块中显式写 proxy_intercept_errors on;,比如 location /api/ 或 location /
- 避免放在 server 或 http 级别——即使写了,子 location 若没配 error_page,照样透传 502
- 不要给静态资源路径(如 .js/.png)也开这个指令,容易干扰 Content-Type,这类请求用 try_files 更合适
error_page 必须成对且可路由
只开拦截不配 error_page,等于装了刹车却没踩下去。每个要接管的状态码都得有明确落点:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 写法示例:error_page 502 503 504 /50x.html;
- 这个 /50x.html 是 URI,不是文件路径,所以必须有对应 location 去响应它
- 推荐这样定义服务该页面的 location:
location = /50x.html { root /usr/share/nginx/html; internal; } - 加 internal 是硬性要求,防止用户直接访问 /50x.html 绕过业务逻辑
确保后端真返回了 50x 状态码
proxy_intercept_errors 只看 HTTP 状态码,不解析响应体内容。常见失效原因其实是后端没按规范返回错误:
- 用 curl -I http://your-upstream 直连后端,确认它在超时、宕机等场景下确实返回 502/504,而不是返回 200 + 错误 JSON
- 如果后端返回空响应体(body 长度为 0),Nginx 默认忽略拦截——需让后端至少返回一个字节,或临时加 proxy_buffering off; 测试验证
- Nginx 自身生成的 502(如 upstream 地址写错、DNS 解析失败)也受此机制控制,只要开了 on 并配了对应 error_page,就能兜底
进阶:差异化降级与状态码伪装
单一页面不够用?可以按故障类型分页,甚至隐藏真实错误码提升体验:
- 为不同错误提供专属提示:error_page 502 /timeout.html; error_page 503 /maintenance.html; error_page 504 /unavailable.html;
- 若不想暴露系统故障,用 =200 强制改状态码:error_page 502 503 504 =200 /fallback.html;
- 结合 map 指令可更灵活,例如根据上游响应头 X-Backend-Status 动态选页,适合多服务混合部署场景










