Express设置超时后300秒报UND_ERR_HEADERS_TIMEOUT如何解决
问题根因
UND_ERR_HEADERS_TIMEOUT是Node.js 18+内置fetch(底层基于undici实现)的专属报错,和你之前调整的Express服务超时、浏览器超时、Swagger端超时都没关系。
内置fetch默认的响应头接收超时恰好是300秒,你在Express路由里调用下游Swagger API时,没有给这个fetch请求单独配置超时,所以到点就被undici主动断开了,之前改的所有配置都没命中这个超时点,自然不生效。
修复方法
给你调用下游的fetch请求显式配置超时阈值即可,两种方案选一个就行:
单请求配置(推荐,不影响其他接口)
先引入Node自带的undici模块(不需要额外npm安装,内置fetch本身就依赖这个包),给fetch加dispatcher参数,修改你原来的getData方法:
const { Agent } = require('undici') async function getData() { return fetch(dataurl, { method: 'GET', headers: { accept: 'application/json;charset=UTF-8', authorization: 'Bearer ' + token.access_token }, dispatcher: new Agent({ headersTimeout: 610000, // 响应头超时设为610秒,留10秒冗余 bodyTimeout: 610000, // 响应体超时同步设置,避免头收到了体传一半超时 }) }) .then(res => res.json()) .catch(error => console.error('Error:', error)); }
全局配置(适合所有fetch调用都需要长超时的场景)
如果你的服务里其他内部fetch调用也需要超过300秒的超时,可以直接在服务入口最顶部修改undici全局默认配置:
const { setGlobalDispatcher, Agent } = require('undici') setGlobalDispatcher(new Agent({ headersTimeout: 610000, bodyTimeout: 610000 }))
补充说明
- 你之前给Express server配置的
requestTimeout、headersTimeout等参数不用删,这些参数控制的是用户浏览器到你的Express服务这一段链路的超时,和Express服务调用下游API的fetch超时是完全独立的两个链路 - 如果你的Express服务前面还挂了Nginx、云负载均衡这类反向代理,记得同步检查代理层的超时配置,但从报错码是undici专属的
UND_ERR_HEADERS_TIMEOUT判断,改完fetch的超时就能解决当前问题 - 10分钟级别的接口请求非常容易因为网络波动、连接复用等问题失败,长期来看更推荐改成异步任务模式:收到请求先返回任务ID,后台跑任务拉取数据,前端轮询或者用websocket推结果,不过如果暂时不调整架构,上面的配置足够解决当前的300秒超时问题
内容的提问来源于stack exchange,提问作者suckerp
相关产品推荐
相关产品推荐

