You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Next.js API路由代理GitHub API时出现ERR_HTTP_HEADERS_SENT错误排查

解决Next.js API路由中的ERR_HTTP_HEADERS_SENT错误

这个错误的核心原因是你多次尝试向客户端发送响应了。咱们来拆解一下问题:

在你的代码里,ghRes.on('data', (d) => { res.json(d); })这行存在问题——HTTP响应是流式传输的,data事件会被触发多次(每次接收到一部分数据块),而你每次触发都调用res.json(),这就相当于多次给客户端发完整的响应头和响应体。当第一次res.json()发送后,HTTP连接的响应头已经被发送给客户端了,后续再调用res.json()就会抛出这个错误。

修正方案:收集完整响应后再返回

你需要先把所有数据块收集起来,等到响应结束(end事件触发)时,再统一解析并返回给客户端。另外还要处理可能的JSON解析错误和请求失败的情况,确保客户端能收到正确的反馈。

修正后的代码如下:

const https = require('https')

export default (req, res) => {
  const options = {
    host: 'api.github.com',
    path: '/search/repositories?q=tetris',
    headers: {'user-agent': 'gohyifan'}
  }

  https.get(options, (ghRes) => {
    // 设置编码,避免直接处理Buffer
    ghRes.setEncoding('utf8');
    let rawData = '';

    // 收集所有数据块
    ghRes.on('data', (chunk) => {
      rawData += chunk;
    });

    // 响应结束时处理完整数据
    ghRes.on('end', () => {
      try {
        const parsedData = JSON.parse(rawData);
        res.status(ghRes.statusCode).json(parsedData);
      } catch (e) {
        console.error('JSON解析错误:', e);
        res.status(500).json({ error: 'Failed to parse GitHub response' });
      }
    });
  }).on('error', (e) => {
    console.error('请求GitHub API失败:', e);
    // 给客户端返回错误响应,避免客户端挂起
    res.status(500).json({ error: 'Failed to fetch data from GitHub' });
  });
}

额外建议:使用fetch简化代码

Next.js环境下其实更推荐使用内置的fetch API,代码会简洁很多,也不容易犯流式处理的错误:

export default async (req, res) => {
  try {
    const response = await fetch('https://api.github.com/search/repositories?q=tetris', {
      headers: {'user-agent': 'gohyifan'}
    });
    
    if (!response.ok) {
      throw new Error(`GitHub API返回错误:${response.status}`);
    }
    
    const data = await response.json();
    res.status(response.status).json(data);
  } catch (e) {
    console.error('请求失败:', e);
    res.status(500).json({ error: e.message });
  }
}

这样不仅代码更易读,还能自动处理流式响应的拼接和解析,减少出错概率。

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

火山引擎 最新活动