You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native获取本地图片报错:RangeError构造Response失败状态码0超出范围

问题:Expo Camera拍照后上传Firebase Storage报错RangeError

我用Expo Camera实现的拍照功能运行正常,代码如下:

//Local Image State object, for file URL, Firebase URL
const [image, setImage] = useState([]);
const [fireURI, setURI] = useState([]); 

const takePicture = async () => {
  // null parameter, options are set on Camera component not in takePicAsync()
  const data = await camera.takePictureAsync(null);
  const source = await data.uri;

  setImage([...image, source]);
  //Renders photo after
  setUploading(true);
  //Closes camera
  setIsCameraOpen(false);
  setZoom(0);
};

但将图片上传至Firebase Storage并获取下载链接的功能,此前正常现在突然报错:"RangeError Failed to construct 'Response': The status provided (0) is outside the range [200, 599]",相关代码如下:

const handleFirebaseURI = async () => {
  const ImageURL = [];
  image.map(async (images) => {
    var metadata = {
      contentType: "image/jpeg",
    };
    // ERROR HERE ON FETCH, if I remove the firebase logic the error still occurs
    const response = await fetch(images);
    const blob = await response.blob();
    const filename = await images.substring(images.lastIndexOf("/") + 1);
    //Reference to Firebase storage, folder created for each user email
    const imageRef = ref(storage, `${ID}/${filename}`);
    try {
      //Uploads Image to Firebase Storage
      const uploadTask = await uploadBytes(imageRef, blob, metadata);
      // Get the download URL and wait for its resolution
      const url = await getDownloadURL(uploadTask.ref);
      ImageURL.push(url);
      setImages({ ImageURL });
      setUploadingToFirebase(true);
    } catch (error) {
      alert(error);
    }
  });
};

请问获取本地文件时出现该错误的原因是什么?此前代码运行正常,可能发生了哪些变化?


回答

这个错误的核心是直接用fetch读取Expo生成的本地文件URI(如file://协议路径)时,出现了非HTTP标准的状态码0,说明文件读取过程中发生了异常,而非HTTP请求的常规错误。以下是可能的原因和变化:

可能的原因及变化点

  • Expo SDK或依赖版本更新:如果近期升级了Expo SDK、Expo Camera或相关依赖,新版本可能修改了本地文件URI的访问规则,或者对fetch读取本地文件的逻辑做了限制,导致原本正常的fetch调用返回异常状态码。
  • 本地临时文件被清理:Expo Camera拍摄的图片默认存在临时目录,系统可能在内存不足、APP重启或后台运行时自动清理这些临时文件。如果image状态中存储的是旧的临时文件URI,再次调用fetch时文件已不存在,就会触发这个错误。
  • 应用权限变更:用户可能在系统设置中关闭了APP的存储/相册访问权限,或者系统版本升级后权限策略收紧,导致APP无法读取本地文件,fetch操作失败返回状态码0。
  • fetch API的隐性行为变化:React Native或Expo的fetch实现可能更新了对本地文件URI的处理逻辑,比如不再支持直接fetch本地file://路径,需要改用专门的文件读取API。
  • 代码逻辑的异步问题:image.map(async (...))的写法会导致多个异步操作并行执行,且不等待所有操作完成。如果某次操作中image状态还未完全更新(比如刚拍完照就触发上传),可能混入了无效的URI,进而引发fetch错误。

修复建议

  1. 改用Expo FileSystem读取文件:避免直接用fetch读取本地URI,改用Expo官方的FileSystem API来获取文件内容,再转换为Blob:
    import * as FileSystem from 'expo-file-system';
    
    // 在handleFirebaseURI中替换fetch部分
    const fileInfo = await FileSystem.getInfoAsync(images);
    if (!fileInfo.exists) {
      console.error('文件不存在:', images);
      return;
    }
    // 读取为base64再转Blob
    const base64 = await FileSystem.readAsStringAsync(images, { encoding: 'base64' });
    const blob = await fetch(`data:image/jpeg;base64,${base64}`).then(res => res.blob());
    
  2. 验证文件有效性:在fetch或读取文件前,先通过FileSystem.getInfoAsync检查文件是否存在,避免读取无效路径。
  3. 修复异步循环逻辑:用Promise.all替代map,确保所有异步上传操作完成后再更新状态:
    await Promise.all(image.map(async (images) => {
      // 上传逻辑
    }));
    setImages({ ImageURL });
    setUploadingToFirebase(true);
    
  4. 检查权限和SDK版本:确认APP已获取存储权限,必要时重新请求;如果是SDK更新导致的问题,可尝试回退到之前正常的版本测试。

内容的提问来源于stack exchange,提问作者VCS-Jacob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:23:22