如何在 React Native 中将 Blob 数据转换为可下载的本地文件

7次阅读

如何在 React Native 中将 Blob 数据转换为可下载的本地文件

本文介绍如何在 react native 中处理后端返回的 blob 类型响应(如含 blobid 的对象),绕过浏览器环境限制,直接将原始二进制数据持久化为本地文件,并实现安全、可靠的客户端下载。

本文介绍如何在 react native 中处理后端返回的 blob 类型响应(如含 blobid 的对象),绕过浏览器环境限制,直接将原始二进制数据持久化为本地文件,并实现安全、可靠的客户端下载。

react native 并不支持 Web 环境中的 Blob 对象或 URL.createObjectURL() API,因此当后端返回类似以下结构的响应时:

{   "_data": {     "blobId": "E582A159-8E6E-48D2-B245-CA62A7005706",     "name": "v1-download-proforma-invoice.json",     "size": 108769,     "type": "application/json"   } }

不能像在 Web 中那样调用 blob.arrayBuffer() 或生成 Object URL。此时需明确:该响应本身通常不包含实际二进制内容,而只是一个服务端 Blob 引用标识——真正的文件数据需通过额外请求(如 response.request._response)获取,前提是请求配置了 responseType: ‘arraybuffer’ 或 ‘blob’(在 axios 中实际生效为原始二进制响应体)。

✅ 正确做法是:

  1. 配置 Axios 请求返回原始响应体(关键!)
    在 useMutation 的请求配置中,显式设置 responseType: ‘arraybuffer’(推荐)或 ‘blob’(部分 RN 版本兼容性较弱):
import { useMutation } from '@tanstack/react-query'; import axios from 'axios';  const downloadFile = async (fileId: string) => {   const response = await axios.get(`/api/files/${fileId}`, {     responseType: 'arraybuffer', // ← 必须!确保获取原始字节流     headers: { Accept: 'application/json' },   });   return response; };  const { mutateAsync: triggerDownload } = useMutation(downloadFile);
  1. 提取并写入本地文件
    使用 react-native-fs(RNFS)将 ArrayBuffer 或 Uint8Array 写入设备存储。注意:response.data 即为原始二进制数据,无需解析 _data.blobId:
import RNFS from 'react-native-fs';  const saveToFile = async (response: AxiosResponse<ArrayBuffer>, fileName: string) => {   const filePath = `${RNFS.DocumentDirectoryPath}/${fileName}`;    // 将 ArrayBuffer 转为 base64 字符串(RNFS.writeFile 仅接受 string | number | object)   const base64Data = Buffer.from(response.data).toString('base64');    await RNFS.writeFile(filePath, base64Data, 'base64');    return filePath; };  // 完整调用示例 const handleDownload = async () => {   try {     const response = await triggerDownload();     const localPath = await saveToFile(response, 'v1-download-proforma-invoice.json');     console.log('文件已保存至:', localPath);      // 可选:使用 react-native-file-viewer 打开     // await FileViewer.open(localPath);   } catch (err) {     console.error('下载失败:', err);   } };

⚠️ 重要注意事项

  • ❌ 不要尝试解析 response.data._data.blobId —— 这是 React Native 内部调试字段,无实际用途,且不同版本可能变化;
  • ✅ 始终依赖 response.data(ArrayBuffer)作为数据源;
  • ? 若接口需鉴权,请确保 axios 请求携带正确 Token(如 Authorization: Bearer xxx),否则 response.data 可能为空或报错;
  • ? 文件路径建议使用 RNFS.DocumentDirectoryPath(iOS/android 均可读写)或 RNFS.CachesDirectoryPath(临时缓存);
  • ? Android 需在 AndroidManifest.xml 中添加存储权限(,Android 10+ 推荐使用 android:requestLegacyExternalStorage=”true” 或适配 Scoped Storage)。

? 总结:React Native 中“Blob 下载”的本质是 二进制流落地存储,核心在于:① Axios 正确配置 responseType 获取原始数据;② 使用 react-native-fs 将 ArrayBuffer 编码为 base64 后写入文件。跳过 Web 语义层(Blob / Object URL),直击移动端文件 I/O 本质,方为可靠实践。

text=ZqhQzanResources