React Native URI图片转ArrayBuffer报错,如何无Base64转Buffer传S3?
Problem Description
我正在尝试把通过react-native-image-picker获取的图片URI转换成ArrayBuffer,这样就能直接用S3的PUT请求上传(因为S3 PUT不支持form-data,没法用那种方式)。我写的代码是这样的:
let fetched = await fetch(pictureInfo.uri) console.log("Fetched uri:", fetched) let arrayBuffer = await fetched.arrayBuffer()
但运行时抛出了错误:Error: FileReader.readAsArrayBuffer is not implemented。想请教下,有没有办法不转Base64,直接把图片转成Buffer然后上传到S3?
Solution
这个问题我之前也碰到过,React Native自带的fetch在处理本地文件URI时,arrayBuffer()方法确实会因为底层FileReader的实现缺失抛出这个错误,尤其是在Android平台上更常见。下面给你几个不用转Base64就能解决的方案:
1. 使用react-native-blob-util(推荐)
这个库专门针对React Native优化了文件和Blob的处理,能完美解决本地URI转ArrayBuffer的问题,而且用法和原生fetch很接近:
首先安装依赖:
npm install react-native-blob-util --save(如果是React Native 0.60+版本,会自动完成链接,无需额外操作)
转换URI到ArrayBuffer的代码:
import ReactNativeBlobUtil from 'react-native-blob-util'; // 从react-native-image-picker获取的图片URI const imageUri = pictureInfo.uri; // 用库的fetch方法读取本地文件 const blobResponse = await ReactNativeBlobUtil.fetch('GET', imageUri); // 直接转换为ArrayBuffer const arrayBuffer = await blobResponse.arrayBuffer();
2. 使用react-native-fs读取文件为Buffer
如果你已经在项目里用到了react-native-fs,也可以用它来读取文件内容,再转换成ArrayBuffer:
安装依赖:
npm install react-native-fs --save代码示例:
import RNFS from 'react-native-fs'; const imageUri = pictureInfo.uri; // 移除URI中的file://前缀(部分平台返回的URI会带这个) const filePath = imageUri.replace('file://', ''); // 读取文件为base64字符串,再转换为Buffer/ArrayBuffer const base64Str = await RNFS.readFile(filePath, 'base64'); const arrayBuffer = Buffer.from(base64Str, 'base64').buffer;注:这里虽然中间用到了base64,但只是作为转换的中间步骤,最终还是得到了ArrayBuffer,并没有把base64作为上传内容,符合你的需求。
3. 上传到S3的示例代码
拿到ArrayBuffer后,就可以直接用PUT请求上传到S3的签名URL了:
const s3SignedUrl = '你的S3预签名PUT地址'; const imageMimeType = pictureInfo.type; // 比如image/jpeg、image/png await fetch(s3SignedUrl, { method: 'PUT', body: arrayBuffer, headers: { 'Content-Type': imageMimeType, // 如果S3签名要求其他头部,也需要加上 }, });
Important Notes
- URI格式检查:确保
react-native-image-picker返回的是file://开头的本地路径,而不是content://格式。可以在配置中设置path相关参数,或者用库提供的工具方法转换格式。 - 权限配置:确保你的App已经申请了读取相册/存储的权限,否则会出现文件读取失败的情况。
内容的提问来源于stack exchange,提问作者nicecatch

