React Native中如何将Blob数据转换成可下载的本地文件?
- 内容介绍
- 文章标签
- 相关推荐
本文共计791个文字,预计阅读时间需要4分钟。
本段文字介绍如何在HTML中使用``标签进行链接,并设置样式。具体步骤如下:
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 中实际生效为原始二进制响应体)。
✅ 正确做法是:
-
配置 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);
-
提取并写入本地文件
使用 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 中添加存储权限(<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />,Android 10+ 推荐使用 android:requestLegacyExternalStorage="true" 或适配 Scoped Storage)。
? 总结:React Native 中“Blob 下载”的本质是 二进制流落地存储,核心在于:① Axios 正确配置 responseType 获取原始数据;② 使用 react-native-fs 将 ArrayBuffer 编码为 base64 后写入文件。跳过 Web 语义层(Blob / Object URL),直击移动端文件 I/O 本质,方为可靠实践。
本文共计791个文字,预计阅读时间需要4分钟。
本段文字介绍如何在HTML中使用``标签进行链接,并设置样式。具体步骤如下:
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 中实际生效为原始二进制响应体)。
✅ 正确做法是:
-
配置 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);
-
提取并写入本地文件
使用 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 中添加存储权限(<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />,Android 10+ 推荐使用 android:requestLegacyExternalStorage="true" 或适配 Scoped Storage)。
? 总结:React Native 中“Blob 下载”的本质是 二进制流落地存储,核心在于:① Axios 正确配置 responseType 获取原始数据;② 使用 react-native-fs 将 ArrayBuffer 编码为 base64 后写入文件。跳过 Web 语义层(Blob / Object URL),直击移动端文件 I/O 本质,方为可靠实践。

