必须在同一location中成对配置proxy_intercept_errors on与error_page指令,前者为拦截开关,后者指定降级页uri;需配合internal location确保安全访问,并通过upstream健康检查主动规避故障。

要让 Nginx 在后端返回 4xx/5xx 错误时统一展示自定义降级页,核心不是只打开 proxy_intercept_errors,而是让它和 error_page 协同工作——前者是拦截开关,后者才是实际响应的执行者。配错任一环节,错误仍会原样透传。
必须在同一 location 中成对启用拦截与绑定错误码
该指令默认关闭,且仅对 proxy_pass 流量生效。不能只写 proxy_intercept_errors on; 就以为万事大吉:
- 在代理请求的
location块中显式开启:proxy_intercept_errors on; - 紧随其后声明要接管的状态码,例如:
error_page 500 502 503 504 /error.html; - 避免把
error_page放在server或http级别而proxy_intercept_errors写在location里——作用域不匹配会导致失效 - 推荐覆盖常见服务级错误:
error_page 400 401 403 404 500 502 503 504 /error.html;
确保降级页可访问且安全返回
error_page 后的路径是 URI,不是文件系统路径,必须有对应 location 处理它:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 添加内部路由:
location = /error.html { internal; root /usr/share/nginx/html; } -
internal防止用户直接访问该页面(如 curl http://domain/error.html) -
root指向真实存放文件的目录,即实际路径为/usr/share/nginx/html/error.html - 静态页建议内联 CSS/JS,避免二次请求失败;文件大小建议大于 512 字节,防止浏览器显示默认错误页
配合 upstream 提升容错能力,减少触发降级概率
拦截是兜底,预防才是关键。让 Nginx 主动避开故障节点,能大幅降低用户看到降级页的次数:
- 在
upstream中配置健康探测:max_fails=2 fail_timeout=30s; - 启用自动重试:
proxy_next_upstream error timeout http_502 http_503 http_504; - 设置合理超时:
proxy_connect_timeout 1s; proxy_read_timeout 3s; - 当所有节点均不可达时,Nginx 自身生成的 502/503/504 仍会被
proxy_intercept_errors拦截并跳转至/error.html
验证是否真正生效的实用方法
别依赖猜测,用命令直击响应本质:
- 用
curl -v http://your-domain/api/fail查看状态码、Content-Type和响应体内容 - 若返回
200 OK+text/html+ 你写的页面内容,说明已成功接管 - 若仍是
502 Bad Gateway或原始后端 HTML,重点检查:后端是否真返回了标准 502(而非连接拒绝)、error_page是否遗漏该状态码、文件路径是否存在且可读










