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




