React Native Expo上传图片至Python API时文件大小为0的问题
问题原因与解决方案
问题原因
- 手动设置
Content-Type导致解析失败:Axios发送FormData时会自动生成带boundary的multipart/form-data请求头,手动指定该头会覆盖自动生成的内容,后端无法正确解析表单数据,最终导致文件内容为空。 - Expo相册URI处理逻辑错误:
ph://是Expo的本地资源标识,直接通过fetch转Blob再转File的流程,在React Native环境下存在兼容性问题,无法正确读取文件内容。 - React Native中
File构造函数的局限性:React Native的FileAPI并非完全兼容浏览器标准,手动创建File对象无法正确封装本地图片的实际内容。
解决步骤
1. 移除手动设置的Content-Type头
删除Axios请求中手动指定的"Content-Type": "multipart/form-data",让Axios自动生成包含boundary的正确请求头。
2. 直接用Expo URI构造FormData项
在React Native中,FormData支持直接传入本地URI对象,无需转换为Blob或File,格式如下:
formData.append('file', { uri: selectedImageUri, name: 'upload.jpeg', type: 'image/jpeg' });
3. 优化后的React Native代码
const uploadImage = async () => { try { if (selectedImageUri != null) { console.log("Image uri: ", selectedImageUri); const formData = new FormData(); // 直接传入URI对象,无需转Blob/File formData.append('file', { uri: selectedImageUri, name: 'upload.jpeg', type: 'image/jpeg' }); // 移除手动设置的Content-Type,由Axios自动处理 const response = await axios.post(`${API_URL}/upload`, formData); console.log('Upload success:', response.data); } } catch (error) { console.error('Error:', error); } };
4. 后端验证与日志增强
在FastAPI代码中添加文件大小日志,确认是否成功接收内容:
app = FastAPI(max_upload_size=1024 * 1024 * 1024) @app.post("/api/upload") async def upload_file(file: UploadFile = File(...)): try: content = await file.read() print(f"Received file size: {len(content)} bytes") # 添加日志验证 file_path = os.path.join(os.getcwd(), file.filename) with open(file_path, "wb") as f: f.write(content) return JSONResponse(content={'file': file.filename}) except Exception as e: return JSONResponse(content={'error': str(e)}, status_code=500)
额外注意事项
- 确保Expo项目已安装并配置
expo-image-picker,同时在app.json中声明权限:{ "expo": { "ios": { "infoPlist": { "NSPhotoLibraryUsageDescription": "需要访问相册以选择图片" } }, "android": { "permissions": ["READ_EXTERNAL_STORAGE"] } } } - Android平台的
content://格式URI,上述FormData构造方式同样适用。
内容的提问来源于stack exchange,提问作者Murali Krishna
相关产品推荐
相关产品推荐

