You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx反向代理:仅拦截自身特定错误的实现方法

如何让Nginx仅处理反向代理自身产生的50x错误

这个需求太常见了——很多时候我们只想处理Nginx代理层自己搞出来的50x错误(比如连不上后端、超时),而上游服务器返回的50x(比如后端代码崩了返回的500)我们想直接透传给用户。下面给你两个实用的方案,都是基于Nginx内置变量来区分错误来源的:

方案一:针对特定代理层错误码直接拦截

大部分情况下,Nginx代理自身产生的50x错误集中在502(网关错误,无法连接后端)和504(网关超时,后端响应太慢),而上游服务器返回的50x多是500、503这类。我们可以直接针对这两个码做自定义处理,其他50x透传:

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://your-backend-server;
        proxy_intercept_errors on; # 必须开启,否则Nginx不会拦截错误

        # 只处理Nginx代理层的502/504错误,跳转到自定义处理location
        error_page 502 504 = @proxy_errors;

        # 上游返回的500/503直接透传原状态码和内容
        error_page 500 503 = $status;
    }

    # 自定义代理错误处理逻辑
    location @proxy_errors {
        # 示例1:返回自定义HTML页面
        return 502 "<!DOCTYPE html>
<html>
<head><title>Proxy Error</title></head>
<body><h1>抱歉,后端服务暂时无法连接</h1></body>
</html>";

        # 示例2:重定向到静态错误页面
        # rewrite ^ /static/proxy-error.html break;
        # root /path/to/your/static/files;
    }
}

这个方案简单直接,适合大多数场景——如果你确认上游不会返回502/504,或者即使返回也不需要拦截,用这个就够了。

方案二:用$upstream_status变量精准区分错误来源

如果需要更严格的区分(比如上游也可能返回502/504,你只想拦截Nginx自己产生的),可以利用$upstream_status变量:

  • 当错误来自上游服务器时,$upstream_status会被设置为上游返回的状态码(比如500、502);
  • 当错误是Nginx代理自身产生的(比如无法连接后端、超时),$upstream_status是空值。

配置示例:

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://your-backend-server;
        proxy_intercept_errors on;

        # 把所有50x错误都转到统一处理location
        error_page 500 502 503 504 = @handle_all_errors;
    }

    location @handle_all_errors {
        # 仅当$upstream_status为空时(代理层错误),执行自定义处理
        if ($upstream_status = "") {
            return 502 "<h1>代理层错误:无法连接或访问后端超时</h1>";
        }

        # 否则透传上游的错误状态码和原始内容
        return $status $upstream_http_content_type $upstream_response_body;
    }
}

这个方案可以精准区分错误来源,不管状态码是什么,只要是Nginx自己搞出来的错误就处理,上游的错误原样返回。

几个关键注意事项

  • 一定要开启proxy_intercept_errors on,否则Nginx会直接把所有上游错误透传,不会触发任何error_page规则;
  • 测试时可以故意把后端地址改成无效IP(触发502),或者设置极短的proxy_connect_timeout(触发504),验证自定义处理是否生效;
  • 如果需要更细致的判断,还可以结合$upstream_response_time变量——上游返回的错误会有响应时间,而代理层错误的这个变量是空值,逻辑和$upstream_status类似。

内容的提问来源于stack exchange,提问作者Rockietto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:58:16