Expo Go视频上传异常求助:iOS崩溃、安卓报网络请求失败
问题分析与修复方案
核心问题1:FormData未实际使用,请求body格式错误
你创建了FormData实例但完全没用到,反而直接把ImagePicker返回的asset对象赋值给body,这会导致请求格式完全不符合后端预期,这是引发两端问题的根本原因:
- iOS端:直接传递asset对象会导致序列化异常,进而引发应用崩溃
- 安卓端:后端无法解析错误的请求体,返回异常导致网络请求失败
核心问题2:未正确处理ImagePicker返回的视频资源
ImagePicker返回的result.assets[0]是一个包含视频信息的对象,不是可直接上传的Blob或File类型,需要通过FileSystem将其转换为二进制文件后再添加到FormData中。
修复后的完整代码示例
- 先确保安装并导入
expo-file-system:
import * as FileSystem from 'expo-file-system';
- 视频选择与状态设置(无需修改原有逻辑,但后续处理要基于asset的uri):
let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Videos, allowsEditing: true, aspect: [4, 3], quality: 1, }); if (!result.canceled) { setUploadFile(result.assets[0]); }
- 修正FormData与请求配置:
// 将asset转换为可上传的Blob const fileUri = uploadFile.uri; const fileType = uploadFile.mimeType || 'video/mp4'; const fileName = fileUri.split('/').pop(); // 通过FileSystem读取文件为Blob const fileBlob = await FileSystem.readAsStringAsync(fileUri, { encoding: FileSystem.EncodingType.Base64, }).then(base64 => { return Blob([Uint8Array.from(atob(base64), c => c.charCodeAt(0))], { type: fileType }); }); // 正确构建FormData const formData = new FormData(); formData.append("file", fileBlob, fileName); // 请求配置:移除手动设置的Content-Type,让浏览器自动处理 const videoOptions = { method: 'POST', headers: { Accept: 'application/json', Authorization: 'Bearer ...', // 不要手动设置Content-Type: multipart/form-data,FormData会自动添加边界标识 }, body: formData // 这里使用正确的FormData作为请求体 };
- API请求(保持原有结构即可):
fetch(postVideos.url, videoOptions) .then(response => response.json()) .then(data => console.log('上传成功:', data)) .catch(error => console.error('上传失败:', error));
额外注意事项
- 确保Expo项目中已安装
expo-image-picker和expo-file-system依赖 - iOS端需要在
app.json中配置相册访问权限:
{ "expo": { "ios": { "infoPlist": { "NSPhotoLibraryUsageDescription": "需要访问相册以选择视频", "NSPhotoLibraryAddUsageDescription": "需要访问相册以保存视频" } } } }
- 安卓端需要在
app.json中配置权限:
{ "expo": { "android": { "permissions": ["READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"] } } }
内容的提问来源于stack exchange,提问作者elijaveto
相关产品推荐
相关产品推荐

