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

React Native中Fetch获取OpenAI流式响应失败问题求助

React Native中Fetch API无法获取response.body实现流式处理OpenAI响应的解决方案

问题概述

通过Node+Express转发OpenAI的流式文本响应到React Native客户端时,React Native的Fetch API不支持ReadableStream,调用response.body返回undefined,无法通过getReader()逐块处理文本。非流式场景下用response.text()可正常获取内容,尝试过RN-fetch-blob、react-native-fetch-api等polyfill均无效。

服务器端已能正常输出分块内容:

Hi
!
How
can
I
assist
you
today
?

服务器端示例代码

app.post("/gptText", async (req, res) => {
  try {
    const requestBody = {
      model: "gpt-4",
      messages: [
        {
          role: "user",
          content: "Say 'hi'",
        },
      ],
      stream: true,
    };

    const completion = await openai.chat.completions.create(requestBody);
    res.setHeader("Content-Type", "text/plain");
    res.setHeader("Transfer-Encoding", "chunked");

    for await (const chunk of completion) {
      const [choice] = chunk.choices;
      const { content } = choice.delta;

      if (content !== undefined) {
        console.log(content);
        res.write(content);
      }
    }

    res.end();
  } catch (error) {
    console.error("Error: ", error);
    res.status(500).json({ error });
  }
});

客户端尝试代码(无效)

const response = await fetch('YOUR_SERVER_URL/gptText', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({/* 请求参数 */})
}).then((response) => {
  console.log(response.body); // 输出undefined
});

可行解决方案

方案1:使用react-native-blob-util处理流式响应

react-native-blob-util是RN-fetch-blob的替代库,支持流式响应处理:

  1. 安装依赖
npm install react-native-blob-util
# 或
yarn add react-native-blob-util
  1. 客户端代码实现
import ReactNativeBlobUtil from 'react-native-blob-util';

const fetchStream = async () => {
  const response = await ReactNativeBlobUtil.fetch('POST', 'YOUR_SERVER_URL/gptText', {
    'Content-Type': 'application/json',
  }, JSON.stringify({/* 请求参数 */}));

  // 获取响应流
  const stream = response.blobStream();
  
  // 逐块读取数据
  stream.onData((chunk) => {
    // 将二进制chunk转为文本
    const text = String.fromCharCode(...new Uint8Array(chunk));
    console.log('收到分块内容:', text);
    // 这里处理文本,比如更新UI
  });

  stream.onEnd(() => {
    console.log('流式响应结束');
  });

  stream.onError((error) => {
    console.error('流式请求出错:', error);
  });
};

方案2:改用Server-Sent Events(SSE)

修改服务器端输出SSE格式的响应,React Native可通过第三方库接收:

  1. 修改服务器端代码
app.post("/gptText", async (req, res) => {
  try {
    const requestBody = {
      model: "gpt-4",
      messages: [
        {
          role: "user",
          content: "Say 'hi'",
        },
      ],
      stream: true,
    };

    const completion = await openai.chat.completions.create(requestBody);
    // 设置SSE响应头
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');

    for await (const chunk of completion) {
      const [choice] = chunk.choices;
      const { content } = choice.delta;

      if (content !== undefined) {
        // 按SSE格式发送数据
        res.write(`data: ${content}\n\n`);
        // 强制刷新响应
        await new Promise(resolve => res.flushHeaders(resolve));
      }
    }

    // 发送结束信号
    res.write('data: [DONE]\n\n');
    res.end();
  } catch (error) {
    console.error("Error: ", error);
    res.status(500).write(`data: {"error": "${error.message}"}\n\n`);
    res.end();
  }
});
  1. 客户端代码(使用react-native-sse库)
npm install react-native-sse
# 或
yarn add react-native-sse
import { EventSource } from 'react-native-sse';

const connectSSE = () => {
  const es = new EventSource('YOUR_SERVER_URL/gptText', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({/* 请求参数 */}),
  });

  es.addEventListener('message', (event) => {
    if (event.data === '[DONE]') {
      es.close();
      console.log('SSE连接结束');
      return;
    }
    console.log('收到SSE内容:', event.data);
    // 处理文本更新UI
  });

  es.addEventListener('error', (error) => {
    console.error('SSE出错:', error);
    es.close();
  });
};

方案3:WebSocket替代HTTP流式

通过WebSocket建立持久连接,实时传输分块数据:

  1. 服务器端添加WebSocket支持(使用ws库)
npm install ws
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
  ws.on('message', async (data) => {
    try {
      const requestBody = JSON.parse(data);
      const completion = await openai.chat.completions.create({
        ...requestBody,
        stream: true,
      });

      for await (const chunk of completion) {
        const [choice] = chunk.choices;
        const { content } = choice.delta;
        if (content !== undefined) {
          ws.send(content);
        }
      }
      ws.send('[DONE]');
    } catch (error) {
      ws.send(JSON.stringify({ error: error.message }));
    }
  });
});
  1. 客户端代码
const ws = new WebSocket('ws://YOUR_SERVER_IP:8080');

ws.onopen = () => {
  // 发送请求参数
  ws.send(JSON.stringify({
    model: "gpt-4",
    messages: [
      { role: "user", content: "Say 'hi'" }
    ]
  }));
};

ws.onmessage = (event) => {
  if (event.data === '[DONE]') {
    ws.close();
    console.log('WebSocket连接结束');
    return;
  }
  console.log('收到WebSocket内容:', event.data);
  // 处理文本更新UI
};

ws.onerror = (error) => {
  console.error('WebSocket出错:', error);
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:27:18