在Next.js项目中对接OpenAI的流式接口时,直接在API路由中转发流式数据可以大幅降低客户端的请求复杂度,同时保证响应的实时性。下面介绍完整的实现方案。

服务端API路由实现
Next.js的API路由需要设置正确的响应头,并且保持连接的流式传输特性,以下是完整的服务端代码实现:
// pages/api/chat.js 或 app/api/chat/route.js(App Router场景)
import { NextResponse } from 'next/server';
export async function POST(request) {
const { messages } = await request.json();
// 调用OpenAI的流式接口
const openaiResponse = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: messages,
stream: true // 开启流式返回
})
});
// 设置响应头,支持流式传输
const responseHeaders = new Headers();
responseHeaders.set('Content-Type', 'text/event-stream');
responseHeaders.set('Cache-Control', 'no-cache');
responseHeaders.set('Connection', 'keep-alive');
// 将OpenAI的流式响应直接转发给客户端
return new NextResponse(openaiResponse.body, {
headers: responseHeaders
});
}
关键配置说明
- 响应头设置:必须设置
Content-Type为text/event-stream,这是SSE(Server-Sent Events)的标准类型,浏览器会自动识别流式数据。 - 缓存控制:设置
Cache-Control: no-cache避免中间层缓存流式数据,保证实时性。 - 连接保持:
Connection: keep-alive确保连接不会在传输过程中被提前关闭。
客户端接收流式数据
客户端可以使用EventSource或者fetch的流式读取能力来处理返回的数据,以下是使用fetch的实现示例:
// 客户端组件中的请求逻辑
async function handleSendMessage() {
const messages = [{ role: 'user', content: '你好,介绍一下Next.js' }];
const response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ messages })
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullContent = '';
// 循环读取流式数据
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
// 解码二进制数据
const chunk = decoder.decode(value, { stream: true });
// 处理OpenAI的SSE格式数据,每行格式为 data: {...}
const lines = chunk.split('n').filter(line => line.trim() !== '');
for (const line of lines) {
if (line.startsWith('data: ')) {
const dataStr = line.slice(6);
if (dataStr === '[DONE]') {
// 流式传输结束
break;
}
try {
const data = JSON.parse(dataStr);
const content = data.choices[0]?.delta?.content || '';
fullContent += content;
// 更新页面显示的文本内容
updateChatContent(fullContent);
} catch (e) {
console.error('解析流式数据失败', e);
}
}
}
}
}
客户端注意事项
- OpenAI的流式返回每条数据都是
data:开头的SSE格式,结尾会用data: [DONE]标记传输完成。 - 使用
TextDecoder处理二进制流时,需要开启stream: true避免部分字符解码错误。 - 更新页面内容时建议使用防抖或者合并更新逻辑,避免频繁触发重渲染导致性能问题。
性能优化建议
为了进一步提升传输效率,可以参考以下优化点:
- 如果使用的是Next.js App Router,可以直接返回
openaiResponse.body作为响应体,减少中间数据处理开销。 - 如果不需要额外的服务端逻辑,可以直接将OpenAI的流式响应透传,避免不必要的JSON解析和重新序列化。
- 生产环境中建议添加请求频率限制和错误重试逻辑,避免OpenAI接口异常导致客户端长时间等待。
注意:如果部署在Vercel等Serverless平台,需要确认平台的流式响应支持情况,部分平台对长连接的支持有限制,可能需要调整超时配置。