React Native Fetch转Blob报错:状态码0不在[200,599]范围内
解决Expo ImagePicker转Blob时的RangeError问题
我需要将通过expo-image-picker选择的图片转换为Blob,上传至AWS S3存储。但使用fetch执行转换时出现错误:RangeError: Failed to construct 'Response': The status provided (0) is outside the range [200, 599],JS引擎为hermes。本地运行代码时触发该错误,在Expo Snack中运行却正常。当前代码如下:
import { Button, StyleSheet, Text, View } from 'react-native'; import * as ImagePicker from 'expo-image-picker' export default function App() { const PickImage = async()=>{ let result = await ImagePicker.launchImageLibraryAsync({ quality:1, mediaTypes:ImagePicker.MediaTypeOptions.Images, }) if(!result.canceled){ let response = await fetch(result.assets[0].uri); let blob = await response.blob(); //code to upload image } } return ( <View style={styles.container}> <Button onPress={PickImage} title='TEST'/> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
问题原因
本地环境(使用Hermes引擎)中,直接用fetch访问file://协议的本地文件URI存在兼容性问题,导致Response构造失败。Expo Snack的运行环境与本地原生环境存在差异,因此未触发该错误。
解决方法
改用expo-file-system处理本地文件并转换为Blob,这是Expo生态中更可靠的本地文件操作方式:
- 安装依赖
npx expo install expo-file-system
- 修改代码
import { Button, StyleSheet, Text, View } from 'react-native'; import * as ImagePicker from 'expo-image-picker'; import * as FileSystem from 'expo-file-system'; export default function App() { const PickImage = async () => { let result = await ImagePicker.launchImageLibraryAsync({ quality: 1, mediaTypes: ImagePicker.MediaTypeOptions.Images, }); if (!result.canceled) { const uri = result.assets[0].uri; // 读取本地文件为base64格式 const base64Data = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64, }); // 将base64转换为Blob const blob = new Blob( [Uint8Array.from(atob(base64Data), char => char.charCodeAt(0))], { type: result.assets[0].mimeType || 'image/jpeg' } ); // 此处编写AWS S3上传逻辑 console.log('Blob生成成功:', blob); } }; return ( <View style={styles.container}> <Button onPress={PickImage} title='TEST' /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
补充说明
expo-file-system是Expo官方提供的文件操作API,对原生环境(包括Hermes引擎)兼容性更好,规避了fetch处理本地文件的问题。- 先读取为base64再转换为Blob的方式,能稳定生成符合AWS S3上传要求的Blob对象。
内容的提问来源于stack exchange,提问作者Niyasin
相关产品推荐
相关产品推荐

