React Native使用react-native-image-picker上传图片偶现网络请求失败排查
React Native ImagePicker 上传图片偶发「TypeError: Network request failed」问题修复
问题根源分析
手动指定 Content-Type 破坏自动边界符生成
当使用FormData作为请求体时,fetch会自动生成包含boundary(分隔符)的multipart/form-data请求头。手动设置'Content-Type': 'multipart/form-data'会覆盖这个自动生成的头部,导致服务器无法正确解析表单数据,这是偶发报错的核心原因。图片类型硬编码不匹配实际文件
代码中固定将图片类型设为image/png,若用户选择JPG、WebP等其他格式的图片,会导致类型不匹配,部分场景下服务器会拒绝请求,触发网络错误。Android 文件URI权限与格式问题
Android平台上,file://开头的URI可能存在访问权限限制,部分缓存文件无法被正常读取,导致请求失败。
修复后的代码示例
FormData 处理部分
// image 示例:file:///data/user/0/com.testApp/cache/rn_image_picker_lib_temp_xxx.jpg import { Platform } from 'react-native'; let formData = new FormData(); // 从imageSelected获取真实文件类型,或 fallback 到默认格式 const actualImageType = imageSelected?.type || 'image/jpeg'; // Android 下移除file://前缀,避免权限问题 const formattedUri = Platform.OS === 'android' ? image.replace('file://', '') : image; // 确保文件名有合理后缀,避免服务器解析异常 const fileName = imageSelected?.fileName || `upload_${Date.now()}.${actualImageType.split('/')[1]}`; formData.append('images', { uri: formattedUri, name: fileName, type: actualImageType }); const response = await updateUserProfile(userDetails, formData);
服务调用部分
export const updateUserProfile = async (userDetails, data) => { const response = await fetch(`${baseUrl}/updateusersprofile/${userDetails._id}`, { method: "PATCH", headers: { Authorization: `Bearer ${userDetails.token}`, // 移除手动设置的Content-Type,让fetch自动生成带boundary的正确头部 }, body: data, }); return response; };
额外注意事项
- 检查
react-native-image-picker的Android配置,确保AndroidManifest.xml中添加必要权限:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - 针对Android 10及以上版本,在
AndroidManifest.xml的application标签中添加android:requestLegacyExternalStorage="true",兼容旧版文件访问逻辑:<application ... android:requestLegacyExternalStorage="true"> </application>
内容的提问来源于stack exchange,提问作者sudhir_arium
相关产品推荐
相关产品推荐

