NextJS API fetch请求300秒超时报TypeError: fetch failed解决方法
问题根源
你写的AbortController超时逻辑不生效,核心是300秒限制是Next.js框架层的服务端执行时长上限,不是原生fetch的默认超时。框架到时间会直接销毁整个服务端请求的执行上下文,你业务代码里的超时逻辑根本来不及触发,自然抛出TypeError: fetch failed错误。
解决方案
根据你的Next.js版本、运行时和部署场景,按以下步骤调整:
1. 基础配置调整(本地开发/自托管场景)
首先在对应长请求的路由文件顶部,导出路由级最大执行时长配置,这个配置优先级最高,同时强制指定使用Node.js运行时:
// 如果你用App Router,在app/api/xxx/route.js 或对应服务端组件页顶部加 // 如果你用Pages Router,在pages/api/xxx.js 或对应SSR页面顶部加 export const runtime = 'nodejs'; // 必须切到Node运行时,Edge运行时硬上限30秒无法修改 export const maxDuration = 3600; // 单位为秒,这里设置为1小时
再修改项目根目录的next.config.js,补充全局配置避免其他限制触发报错:
/** @type {import('next').NextConfig} */ const nextConfig = { experimental: { // 如果你用Server Actions提交长任务,加这个配置 serverActions: { timeout: 3600 } }, api: { responseLimit: false, // 关闭默认响应体大小限制 bodyParser: { sizeLimit: '8mb' // 按你的请求体大小按需调整 } } } module.exports = nextConfig
2. 部署场景额外注意
- 如果你部署在Vercel类Serverless平台,平台本身有套餐级硬时长限制:免费版最高10秒,Pro版默认300秒,企业版最高900秒,超过限制的长请求无法通过改配置突破,需要改成异步任务队列模式:接口收到请求后立刻返回任务ID,后台跑优化任务,前端轮询任务结果,不要同步等待接口返回。
- 如果你自己部署服务且前面套了Nginx/CDN反向代理,需要同步修改代理层配置:把
proxy_read_timeout、proxy_send_timeout参数调整为3600秒,否则代理层到点会先断开连接,一样触发fetch报错。
3. 原有fetch逻辑优化
你的AbortController写法逻辑是对的,补充错误捕获和配置即可:
const OPTIMIZATION_TIMEOUT = 3600000 // 1小时 const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(new Error('优化计算超时,超过1小时未返回结果')), OPTIMIZATION_TIMEOUT); try { const omURL = formulasURL + "optimize/resourceallocationmt"; const omResponse = await fetch(omURL, { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(optimization_data), signal: controller.signal, keepalive: true }) const omData = await omResponse.json(); // 正常处理返回结果 } catch (err) { if (err.name === 'AbortError') { // 单独处理主动超时逻辑 console.error(err.message) } throw err } finally { clearTimeout(timeoutId); }
内容的提问来源于stack exchange,提问作者Eytor Helgason
相关产品推荐
相关产品推荐

