React Native(Expo)流式分片获取失败:返回完整文本而非分片
React Native Expo 流式Fetch无法分片返回数据的解决办法
问题描述
同一段代码在Node.js环境能正常按分片返回数据,但在Expo构建的React Native应用中,无法实现流式分片获取,而是等待全部数据加载完成后一次性返回完整文本。已配置Fetch Polyfill支持流式传输,但问题仍存在。
原实现代码:
import { polyfill, polyfill as polyfillFetch, } from "react-native-polyfill-globals/src/fetch"; import "react-native-get-random-values"; import "react-native-url-polyfill/auto"; import { ReadableStream } from "web-streams-polyfill"; import "text-encoding-polyfill"; globalThis.ReadableStream = ReadableStream; polyfill(); const fetchData = async () => { console.log("fetch"); const response = fetch( "https://sample.lambda-url.us-east-1.on.aws/", { reactNative: { textStreaming: true }, method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ query: "how are you ?", }), } ).then((response) => response.body) .then( async (body) => { const reader = body.getReader() const decoder = new TextDecoder("utf-8"); while (true) { const { value, done } = await reader.read() if (done) { break } const decodedChunk = decoder.decode(value, { stream: true }) console.log(decodedChunk); } }); };
可能的原因及解决步骤
1. 调整Polyfill加载顺序
当前Polyfill的加载顺序可能导致ReadableStream没有被正确注入到全局环境,或者fetch polyfill没有优先使用正确的流式实现。调整加载顺序,确保流式相关的Polyfill先被初始化:
// 先加载流式相关Polyfill import { ReadableStream } from "web-streams-polyfill"; import "text-encoding-polyfill"; // 再加载其他基础Polyfill import "react-native-get-random-values"; import "react-native-url-polyfill/auto"; // 最后加载fetch Polyfill import { polyfill } from "react-native-polyfill-globals/src/fetch"; // 提前挂载ReadableStream到全局 globalThis.ReadableStream = ReadableStream; // 执行fetch polyfill polyfill();
2. 验证服务端的分块传输配置
确保后端服务返回的响应头包含Transfer-Encoding: chunked,并且确实在分块输出数据。如果服务端是一次性输出全部内容,即使客户端配置了流式,也会等待完整数据返回。
可以用curl命令测试服务端响应:
curl -v -X POST -H "Content-Type: application/json" -d '{"query": "how are you ?"}' https://sample.lambda-url.us-east-1.on.aws/
查看响应头是否有Transfer-Encoding: chunked,并且输出是逐步出现的。
3. 替换为react-native-fetch-blob实现流式
如果Expo的原生fetch仍无法支持流式,可以尝试使用react-native-fetch-blob(注意Expo环境需要配置兼容),它对分块传输的支持更稳定:
import RNFetchBlob from 'react-native-fetch-blob'; const fetchData = async () => { console.log("fetch"); RNFetchBlob.fetch('POST', 'https://sample.lambda-url.us-east-1.on.aws/', { 'Content-Type': 'application/json', }, JSON.stringify({ query: "how are you ?" })) .stream((response) => { response.open() .then((resp) => { resp.read((chunk) => { if (chunk === null) { // 流结束 return; } const decodedChunk = new TextDecoder('utf-8').decode(chunk, { stream: true }); console.log(decodedChunk); }); }); }); };
4. 检查Expo SDK版本兼容性
某些Expo SDK版本对fetch流式的支持存在bug,尝试升级到最新稳定版的Expo SDK,或者查看对应版本的Release Notes确认流式传输的支持状态。
内容的提问来源于stack exchange,提问作者Chetan Khanna
相关产品推荐
相关产品推荐

