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

Next.js API路由二次请求报AxiosError: socket hang up ECONNRESET如何修复?

问题:Next.js API路由首次请求正常,后续请求报错socket hang up (ECONNRESET)

我的Next.js API路由首次请求运行正常,但在不重启服务器的情况下发起后续请求时,通常会执行到打印“GO4”的步骤,随后长时间等待后抛出如下错误:

AxiosError: socket hang up
    at AxiosError.from (/Users/xyz/Desktop/Projects/xyz/Project/API/node_modules/axios/dist/node/axios.cjs:725:14)
    at RedirectableRequest.handleRequestError (/Users/xyz/Desktop/Projects/xyz/Project/API/node_modules/axios/dist/node/axios.cjs:2467:25)
    at RedirectableRequest.emit (node:events:525:35)
    at eventHandlers.<computed> (/Users/xyz/Desktop/Projects/xyz/Project/API/node_modules/follow-redirects/index.js:14:24)
    at ClientRequest.emit (node:events:513:28)
    at TLSSocket.socketOnEnd (node:_http_client:518:9)
    at TLSSocket.emit (node:events:525:35)
    at endReadableNT (node:internal/streams/readable:1359:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
    code: 'ECONNRESET'
}

对应的Next.js API路由代码如下:

import Cors from 'cors'
import FormData from 'form-data';

const axios = require('axios');
const form = new FormData();

const cors = Cors({
  methods: ['POST', 'GET', 'HEAD']
})

export const config = {
  api: {
    responseLimit: false
  }
}


export default async function handler(req, res) {

  try {

    const imageBuffers = [];

    await runMiddleware(req, res, cors);

    const body = JSON.parse(req.body);

    for (const image of body.images) {
      
      const response = await axios.get(image, {responseType: 'arraybuffer'});
      if(((response.headers['content-type']).match(/(image)+\//g)).length == 0){
        res.send("Invalid image URL");
      }
      imageBuffers.push(Buffer.from(response.data, 'binary'));
    }

    form.append('...', body.title);

    for (const i in imageBuffers) {
      form.append('images', imageBuffers[i], 'Image'+i+'.jpg');
    }

    const response = await axios.post(
      'url',
      form,
      {
          headers: {
              "Content-Type": "multipart/form-data",
              'Authorization': 'Bearer xyz'
          }
      }
    );
    console.log("DATA: "+JSON.stringify(response.data));
    res.send(JSON.stringify(response.data));

  } catch(err) {

    console.log("ERROR");
    console.error(err);
    res.send(err);

  }

}


function runMiddleware(req,res,fn) {
  return new Promise((resolve, reject) => {
    fn(req, res, (result) => {
      if (result instanceof Error) {
        return reject(result)
      }
      return resolve(result)
    })
  })
}

修复方案

核心问题

问题出在模块级的FormData实例:const form = new FormData()定义在handler函数外部,Next.js的API路由在服务器启动后会常驻内存,第一次请求使用该form对象后,其内部的数据流状态已经改变,后续请求复用这个已被使用过的form对象,会导致表单数据异常,最终触发socket连接被重置的错误(ECONNRESET)。

具体修复步骤

  • 将FormData实例移到handler内部:每次请求都创建全新的FormData对象,避免复用旧实例
  • 修正无效图片URL的响应逻辑:发送错误响应后立即return,阻止后续代码执行
  • 正确设置multipart请求头:手动设置Content-Type: multipart/form-data会丢失自动生成的boundary,应该让axios从FormData对象自动获取headers,或者使用form.getHeaders()
  • 优化图片类型检测逻辑:避免match返回null时调用length方法导致报错

修改后的完整代码

import Cors from 'cors'
import FormData from 'form-data';
const axios = require('axios');

const cors = Cors({
  methods: ['POST', 'GET', 'HEAD']
})

export const config = {
  api: {
    responseLimit: false
  }
}

export default async function handler(req, res) {
  try {
    const imageBuffers = [];
    await runMiddleware(req, res, cors);
    const body = JSON.parse(req.body);

    for (const image of body.images) {
      const response = await axios.get(image, {responseType: 'arraybuffer'});
      // 优化图片类型检测,避免match返回null报错
      const isImage = response.headers['content-type']?.includes('image/');
      if (!isImage) {
        res.send("Invalid image URL");
        return; // 发送错误后终止后续执行
      }
      imageBuffers.push(Buffer.from(response.data, 'binary'));
    }

    // 每次请求创建新的FormData实例
    const form = new FormData();
    form.append('...', body.title);

    for (const i in imageBuffers) {
      form.append('images', imageBuffers[i], `Image${i}.jpg`);
    }

    const response = await axios.post(
      'url',
      form,
      {
        headers: {
          // 使用FormData自动生成的headers,包含正确的boundary
          ...form.getHeaders(),
          'Authorization': 'Bearer xyz'
        }
      }
    );
    console.log("DATA: "+JSON.stringify(response.data));
    res.send(JSON.stringify(response.data));

  } catch(err) {
    console.log("ERROR");
    console.error(err);
    res.status(500).send(err.message); // 使用正确的状态码返回错误
  }
}

function runMiddleware(req,res,fn) {
  return new Promise((resolve, reject) => {
    fn(req, res, (result) => {
      if (result instanceof Error) {
        return reject(result)
      }
      return resolve(result)
    })
  })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 04:15:41