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

Next.js 13项目中获取OpenAI流式响应无返回问题求助

问题排查与修复方案

API路由(sendMessage.js)问题修复

  1. 请求体参数错误:OpenAI Chat Completions API要求对话数组参数为messages,你写成了message,这会导致API无法识别请求内容。
  2. 错误处理缺失响应返回:catch块仅打印错误但未返回错误响应,前端无法感知后端错误。
  3. Next.js 13 流式响应配置:需要明确启用动态渲染或Edge Runtime,否则静态优化会阻断流式传输。

修复后的API路由代码:

export const runtime = 'edge'; // 启用Edge Runtime,支持流式响应
export const dynamic = 'force-dynamic'; // 强制动态渲染

export default async function handler(req) {
  try {
    const { message } = await req.json();
    const stream = await OpenAIEdgeStream(
      "https://api.openai.com/v1/chat/completions",
      {
        headers: {
          Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
          "content-type": "application/json",
        },
        method: "POST",
        body: JSON.stringify({
          model: "gpt-3.5-turbo",
          messages: [{ content: message, role: "user" }], // 修正为messages
          stream: true,
        }),
      }
    );

    return new Response(stream);
  } catch (error) {
    console.error("Error in API:", error.message);
    // 返回错误响应给前端
    return new Response(JSON.stringify({ error: error.message }), {
      status: 500,
      headers: { "Content-Type": "application/json" }
    });
  }
}

前端页面代码修复

  1. 缺失streamReader实现:需要编写函数解析OpenAI的SSE流式响应格式(每行以data: 开头,data: [DONE]表示结束)。
  2. 渲染流式内容:在回调中更新页面内容,而不是仅打印到控制台。

修复后的前端代码:

// 实现streamReader函数
async function streamReader(reader, onChunk) {
  const decoder = new TextDecoder();
  let buffer = '';

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    buffer += decoder.decode(value, { stream: true });
    // 按行分割处理SSE格式
    const lines = buffer.split('\n');
    buffer = lines.pop(); // 保留未完成的最后一行

    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const data = line.slice(6).trim();
        if (data === '[DONE]') continue; // 忽略结束标记
        try {
          const chunk = JSON.parse(data);
          const content = chunk.choices[0]?.delta?.content;
          if (content) {
            await onChunk(content); // 传递单块内容
          }
        } catch (e) {
          console.error('解析流式数据失败:', e);
        }
      }
    }
  }
}

// 调用API并处理流式响应
try {
  const res = await fetch("/api/chat/sendMessage", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      message: messageText,
    }),
  });

  if (!res.ok) {
    const errorData = await res.json();
    throw new Error(errorData.error || '请求失败');
  }

  const data = res.body;
  if (!data) throw new Error('响应体为空');

  const reader = data.getReader();
  // 假设页面有一个id为"response-content"的元素用于渲染
  const responseElement = document.getElementById('response-content');
  await streamReader(reader, (content) => {
    responseElement.textContent += content; // 逐块追加内容
    console.log(content);
  });
} catch (error) {
  console.error("Error:", error.message);
  // 可以在这里显示错误提示给用户
}

额外检查项

  • 确认process.env.OPENAI_API_KEY已正确配置,且密钥有Chat Completions API的权限。
  • 检查网络请求是否跨域(Next.js API路由同域的话无需担心,但如果部署后需要确认CORS配置)。
  • 确认OpenAIEdgeStream函数正确处理了流式响应,该函数应该返回一个ReadableStream对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:25:58