Nginx网络异常兜底需分层拦截:协议层用default_server(如listen 80 default_server;配return 444)处理非法Host、IP直连等;应用层用error_page配合proxy_intercept_errors拦截后端错误并返回统一JSON响应。

Nginx 中处理网络异常的兜底,核心是分层拦截:协议层用 default_server 拦未匹配域名和非法访问,应用层用 error_page 统一响应后端故障,两者配合才能覆盖绝大多数异常场景。
用 default_server 拦协议层异常
这是最前置的兜底,针对 Host 头不合法、IP 直连、SNI 不匹配、空 Host、伪造协议等请求,必须靠显式配置的 default_server 主动接管:
- HTTP 端口写:
listen 80 default_server;,搭配return 444;(静默断连)或return 403; - HTTPS 端口必须额外写:
listen 443 ssl http2 default_server;,并配有效证书(哪怕自签名),否则 TLS 握手失败不可控 - IPv6 要单独声明:
listen [::]:80 default_server;和listen [::]:443 ssl default_server;,漏掉会导致 IPv6 请求穿透 -
server_name在这里不起作用,写_或留空都行,真正生效的是default_server标志
用 error_page 拦应用层错误
当后端服务返回 404/500/502/503/504 等状态码时,error_page 可拦截并返回统一页面或兜底数据,避免暴露原始错误:
- 启用拦截:
proxy_intercept_errors on;(必须加在 location 块内) - 统一跳转:
error_page 404 500 502 503 504 =200 /default_api;(加=200强制改状态码) - 兜底响应页需用
internal;保护:location = /default_api { internal; default_type application/json; return 200 '{"code":-1,"msg":"service unavailable"}'; } - 若返回静态 HTML,记得配
location = /50x.html { root /usr/share/nginx/html; internal; }
防恶意扫描与畸形请求
很多异常来自僵尸工具或扫描器,它们常省略 Host、用 HTTP/1.0、伪造 UA,需组合策略过滤:
- 强制 Host 存在:
if ($host = "") { return 444; }(放在 server 块顶层,不在 location 内) - 拦截常见爬虫 UA:
if ($http_user_agent ~* "Scrapy|sqlmap|Nikto|ZmEu") { return 403; } - 空 UA 单独匹配:
if ($http_user_agent = "") { return 403; } - robots.txt 必须精确匹配:
location = /robots.txt { default_type text/plain; add_header Content-Type "text/plain; charset=UTF-8"; }
返回兜底数据而非错误页
对 API 接口,返回结构化兜底数据比 HTML 更实用,前端可直接渲染:
- 定义 upstream 后,在 proxy location 中开启:
proxy_next_upstream error timeout http_503; - 用
error_page指向一个 JSON 响应块,内容可内联(如上例),也可从文件读取:return 200 '/path/to/fallback.json';(需配合alias或root) - 确保兜底响应 MIME 正确:
default_type application/json;,避免前端解析失败


















