使用Expo ImagePicker与Firebase Storage时遇RangeError求助
解决RangeError: Failed to construct 'Response' 状态码0超出范围的问题
为啥会报错?
你用fetch()去请求Expo ImagePicker返回的本地文件URI(一般是file://开头的路径),但fetch是用来发起HTTP请求的API,根本处理不了本地文件,所以返回了状态码0——这个码不在HTTP标准的200-599范围内,直接触发了RangeError。
怎么改?
别用fetch读本地文件,改用Expo的FileSystem模块来处理,下面给两种可行方案:
方案1:用FileSystem转Blob上传
先安装依赖:
npx expo install expo-file-system
替换原代码里的fetch相关部分:
import * as FileSystem from 'expo-file-system'; // ... 你的循环代码 for (let i = 0; i < images.length; i++) { const fileName = Date.now() + i; const storageRef = ref( storage, `images/clinics/${auth.currentUser.uid}/${fileName}` ); clinicImag.push({img:`${fileName}`, isMainImg: true}); // 检查文件是否存在 const fileInfo = await FileSystem.getInfoAsync(images[i].img); if (!fileInfo.exists) { console.error(`找不到文件:${images[i].img}`); continue; } // 读取文件为base64,再转成Blob const base64Data = await FileSystem.readAsStringAsync(images[i].img, { encoding: FileSystem.EncodingType.Base64, }); const blob = new Blob([base64ToUint8Array(base64Data)], { type: 'image/jpeg' }); const metadata = { contentType: 'image/jpeg', }; const snapshot = await uploadBytes(storageRef, blob, metadata); const uri = await getDownloadURL(snapshot.ref); clinicImagesURI.push({img: uri, isMainImg: images[i].isMainImg}) } // 辅助函数:把base64转成Uint8Array function base64ToUint8Array(base64) { const raw = atob(base64); const uint8Array = new Uint8Array(raw.length); for (let i = 0; i < raw.length; i++) { uint8Array[i] = raw.charCodeAt(i); } return uint8Array; }
方案2:直接用uploadString上传(更省事)
如果不想转Blob,直接上传base64字符串也行:
import * as FileSystem from 'expo-file-system'; // ... 循环内代码 const base64Data = await FileSystem.readAsStringAsync(images[i].img, { encoding: FileSystem.EncodingType.Base64, }); // 直接上传base64格式的文件 const snapshot = await uploadString(storageRef, base64Data, 'base64', { contentType: 'image/jpeg', }); const uri = await getDownloadURL(snapshot.ref);
额外提醒
- 确认ImagePicker返回的URI是有效的,打印出来看看是不是
file://开头的本地路径 - Android平台要注意权限,确保你的应用已经申请了读取媒体文件的权限
- 加个文件存在检查,避免因为文件不存在导致后续报错
内容的提问来源于stack exchange,提问作者Radu Popescu
相关产品推荐
相关产品推荐

