proxy_intercept_errors本身不替换页面,仅开启错误响应拦截能力,必须与同location块中的error_page指令配合才能完成接管、跳转和页面替换;需显式声明状态码并指向由internal location提供的可访问uri,且后端响应须为非空的4xx/5xx状态码。

proxy_intercept_errors 本身不替换页面,它只是让 Nginx 有机会接管上游返回的 4xx/5xx 错误响应;真正完成拦截、跳转和页面替换的,是它必须搭配的 error_page 指令。配置要闭环,缺一不可。
必须在同一 location 块中开启并绑定状态码
只写 proxy_intercept_errors on; 不起作用,必须紧跟着声明你要接管哪些状态码,并指向一个可访问的资源:
- 在含
proxy_pass的 location 中添加:proxy_intercept_errors on; error_page 404 500 502 503 504 /error.html;
-
/error.html是 URI 路径,不是文件系统路径,需有对应location = /error.html块提供服务 - 推荐覆盖这五类最常见错误:
404(路径不存在)、500(服务内部错)、502/503/504(网关/服务不可用/超时)
确保错误页能被安全、正确地返回
Nginx 默认不会把 /error.html 当作静态文件直接读取,必须显式定义它的服务方式:
- 添加内部 location,防止用户绕过业务直接访问:
location = /error.html { internal; root /usr/share/nginx/html; # 或用 alias:alias /usr/share/nginx/html/error.html; } - 页面文件(如
/usr/share/nginx/html/error.html)需存在,且 Nginx 进程有读取权限 - 若希望统一返回
200 OK(比如做降级展示),写成:error_page 502 503 504 =200 /error.html;
让拦截真正生效的三个关键细节
Nginx 不会无条件拦截——只有满足全部条件,才会放弃透传、执行 error_page:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 后端响应状态码必须是
≥400的标准 HTTP 错误码(如502),不是200+ JSON 错误体 - 响应体不能为空;若后端返回空 body(如
HTTP/1.1 502但没发任何内容),Nginx 默认跳过拦截- 解决办法:让后端至少返回一个字节(如
<p>Down</p>),或在 Nginx 中临时加proxy_buffering off;测试
- 解决办法:让后端至少返回一个字节(如
-
proxy_intercept_errors on和error_page必须在同一作用域(同个location或其父级server),否则不生效
验证是否配置成功
别只看配置语法,要实测响应行为:
- 用
curl -I http://your-domain/bad-path查看是否返回200(说明已接管)或仍是502(说明未触发) - 检查 access log 中
$status(Nginx 返回码)和$upstream_status(后端原始码)是否分离,例如:200 502表示已用自定义页覆盖原始错误 - 查 Nginx error log,若出现
open() "/usr/share/nginx/html/error.html" failed (13: Permission denied),说明权限或路径不对
不复杂但容易忽略










