← 返回资讯

上游返回JSON错误到客户端却成了HTML,怎样查Nginx错误页拦截

2026-10-24

proxy_intercept_errors与error_page可能把上游JSON错误改成自定义HTML。先对照拦截开关核对状态、Content-Type、正文和认证头,再判断错误契约在哪一层改变;这与错误被缓存是不同问题。

保留上游原始错误样本

SDK期待JSON,收到HTML时常先报解析错误,真正的401或503原因反而被遮住。检查应从原始HTTP响应开始,不要只看客户端异常字符串。自定义错误页可能保持原状态,也可能通过等号配置改变状态,因此“页面更友好”不能保证API调用者仍能按原协议处理。

核对intercept_errors与error_page

假上游分别返回401和503的JSON,Nginx关闭拦截时客户端得到对应JSON;开启拦截并配置HTML错误页后,状态仍分别为401和503,正文类型变为text/html。附件把每次完整响应字节、头和状态放进JSON结果,认证挑战头也可直接比较。

error_page没有等号改码时会保留原错误状态,但替换正文仍足以破坏SDK的JSON解析。接入方应同时记录原始状态和正文类型,避免只上报JSONDecodeError。透传认证挑战头与保留结构化错误是接口兼容的一部分,不能为了统一错误页把所有后端失败改成成功状态。

说明内部跳转可能改变方法与状态

关闭拦截只能恢复这一层的透传行为,不会解决上游鉴权失败或服务不可用。真实配置还可能在CDN、应用中间件和更外层代理改写响应;排查时应逐跳比对。本文没有启用缓存,也不将一次响应被改写误解成恢复后继续命中旧错误。

适用范围:只比较本地合成错误;不声称关闭拦截解决鉴权根因或所有上游错误透传问题。

配套样本与复核入口

  • run.py:独立运行程序,包含合成输入、操作和正反例断言。
  • case.json:输入说明、预期任务与适用范围,便于保存和交接。
  • observed.json:本次实际执行输出;临时路径、进程号和计时可能随运行变化。

程序依次记录关闭拦截的401、503和开启拦截的401、503,共四份原始响应。先核对状态,再核对Content-Type与正文,最后比较WWW-Authenticate。JSON与HTML差异在同一次响应上即可看见,不需要引入缓存、重试或真实Key;保留这些限制,才能把错误归因到代理错误页处理。

Linux、Python3.8以上与Nginx1.28.0,设置NGINX_BIN为可执行文件绝对路径;鉴权题还需编译启用http_auth_request_module。程序显式指定新建prefix、配置、pid和日志,所有监听均为回环高端口,绝不向已有master发送控制命令。

python3 -B run.py

阅读输出时,先按case.json中的任务逐项核对Nginx网关JSON错误变HTML,再与observed.json比较。非零退出表示依赖或断言需要处理,应保留实际错误。

一手依据1(proxy_intercept_errors决定>=300上游响应传递或交error_page处理;不意味着自动缓存失败。);一手依据2(error_page将指定错误状态交给内部URI处理;不带等号改码的错误页保留原错误状态,正文及响应头需按实际内部处理结果核对,不保证全部上游头自动透传。)。

继续阅读:网关前置鉴权服务挂了会不会放行,怎样验证auth_request状态矩阵;API路径被静态资源正则接走了,怎样核对Nginx的location选择顺序;上游已恢复却持续收到旧失败,怎样核对代理是否缓存了错误响应。

加微信,把这一页发到你手机上

扫码加站长企业微信,会自动把这一页的链接发给你。模型接入、token 计费上有问题,也可以直接问。

去留微信

不想自己搭网关、自己维护渠道?

力达云是托管的 OpenAI / Anthropic 双格式端点,一期提供 DeepSeek,注册送 ¥5 额度。

去试用

这个页面有问题?

提交时会附带当前页面地址和浏览器信息,帮助我们定位问题。不填联系方式即为匿名。