Next.js中转Azure OpenAI流式响应报错:未返回响应致请求停滞
解决Next.js API路由转发Azure OpenAI流式响应的未响应报错问题
核心原因
该报错表明你的API路由未正确向客户端发送完整响应。流式场景下不能依赖Next.js默认响应逻辑,必须手动管理响应流的开启、数据写入与关闭流程。
具体修复方案
1. 配置流式响应头
在pages/api/gpt.js中,先设置符合流式传输要求的响应头,确保客户端能持续接收数据:
export default async function handler(req, res) { // 开启流式响应的关键头配置 res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Transfer-Encoding': 'chunked' }); // 后续Azure OpenAI请求逻辑... }
2. 逐块转发Azure OpenAI的流式响应
调用Azure OpenAI接口时,获取响应的可读流,按SSE格式逐块写入客户端响应:
const azureOpenAIConfig = { endpoint: process.env.AZURE_OPENAI_ENDPOINT, deployment: process.env.AZURE_OPENAI_DEPLOYMENT, apiKey: process.env.AZURE_OPENAI_API_KEY, apiVersion: process.env.AZURE_OPENAI_API_VERSION }; try { const aiResponse = await fetch( `${azureOpenAIConfig.endpoint}/openai/deployments/${azureOpenAIConfig.deployment}/chat/completions?api-version=${azureOpenAIConfig.apiVersion}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'api-key': azureOpenAIConfig.apiKey }, body: JSON.stringify({ ...req.body, stream: true // 必须开启流式返回 }) } ); if (!aiResponse.ok) { throw new Error(`Azure API请求失败: ${aiResponse.status}`); } // 读取流式数据并转发 const reader = aiResponse.body.getReader(); const decoder = new TextDecoder('utf-8'); while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value); // 过滤无效块,保留有效SSE数据 const validLines = chunk.split('\n').filter(line => { const trimmed = line.trim(); return trimmed !== '' && trimmed !== 'data: [DONE]'; }); validLines.forEach(line => { const data = line.replace(/^data: /, ''); res.write(`data: ${data}\n\n`); // 按SSE规范写入响应 }); } // 手动结束响应流 res.end(); } catch (error) { // 错误场景下发送错误信息并结束流 res.write(`data: ${JSON.stringify({ error: error.message })}\n\n`); res.end(); }
3. 避免Next.js默认响应干扰
Pages Router下,不要在API路由函数末尾返回res.json()或类似响应对象,必须通过res.end()手动结束流式响应;若使用App Router(app/api/gpt/route.js),需返回NextResponse的流式实例替代默认处理。
4. 前端流式请求适配
前端调用API时,需对应处理流式响应:
async function requestStream() { const response = await fetch('/api/gpt', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ messages: [{ role: 'user', content: '请介绍下流式响应' }] }) }); if (!response.ok) throw new Error('请求失败'); const reader = response.body.getReader(); const decoder = new TextDecoder('utf-8'); while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value); const validLines = chunk.split('\n').filter(line => { const trimmed = line.trim(); return trimmed !== '' && trimmed !== 'data: [DONE]'; }); validLines.forEach(line => { const data = JSON.parse(line.replace(/^data: /, '')); // 处理返回内容,比如更新页面UI console.log(data.choices[0].delta.content); }); } }
关键检查项
- 确认Azure OpenAI请求的
stream参数设为true - 确保API路由无提前返回逻辑,必须调用
res.end()结束流 - 检查是否有未捕获的异常导致响应流未正常关闭
内容的提问来源于stack exchange,提问作者Yafaa Ben Tili
相关产品推荐
相关产品推荐

