Expo React Native音频上传至服务器报400错误求助
问题背景
在Expo React Native中使用expo-av和expo-file-system录制音频,保存为MP3后上传至.NET Core服务器,Postman测试正常,但代码上传返回400错误请求。
可能原因及解决方案
1. 手动设置Content-Type导致FormData边界丢失
axios发送FormData时,会自动生成并添加带边界(boundary)的Content-Type头,手动设置'Content-Type': 'multipart/form-data'会丢失关键的边界信息,后端无法正确解析表单数据。
解决方法:删除手动设置的Content-Type头,让axios自动处理。
修改后的请求代码:
const response = await axios.post( `http://192.168.10.16/erp-pronounciation/pronunciation/file/uk`, formData // 移除手动设置的headers );
2. 文件URI格式不兼容跨平台
Expo的FileSystem.documentDirectory在iOS上返回的路径是file:///开头,Android上直接使用该格式可能导致后端无法识别文件。
解决方法:根据平台调整URI格式:
- iOS:保留
file://前缀 - Android:移除
file://前缀
修改文件URI处理代码:
import { Platform } from 'react-native'; // ... const formData = new FormData(); const fileUri = Platform.OS === 'android' ? filePath.replace('file://', '') : filePath; formData.append('file', { uri: fileUri, type: 'audio/mpeg', name: 'recording.mp3', });
3. 录制的实际格式与后缀名不符
Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY的默认录制格式并非MP3:
- iOS默认是M4A(
audio/mp4) - Android默认是3GP或其他格式
直接修改文件后缀为.mp3但实际格式未转换,后端通过Path.GetExtension(file.FileName)获取的扩展名是mp3,但文件实际格式不匹配,触发校验错误。
解决方法:指定录制格式为MP3,或者转换录制后的文件格式:
方法一:指定录制配置为MP3
修改prepareToRecordAsync的配置:
await recording.prepareToRecordAsync({ ...Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY, android: { extension: '.mp3', outputFormat: Audio.RECORDING_OPTION_ANDROID_OUTPUT_FORMAT_MPEG_4, audioEncoder: Audio.RECORDING_OPTION_ANDROID_AUDIO_ENCODER_AAC, // 部分设备支持MP3编码器,可尝试替换: // audioEncoder: Audio.RECORDING_OPTION_ANDROID_AUDIO_ENCODER_MPEG_LAYER_3, }, ios: { extension: '.mp3', outputFormat: Audio.RECORDING_OPTION_IOS_OUTPUT_FORMAT_MPEG4AAC, }, });
方法二:转换录制后的文件为MP3
如果直接指定录制格式有兼容性问题,可在录制完成后转换格式:
// 停止录制后 const { uri: originalUri } = recording; const convertedUri = `${fileDirectory}converted.mp3`; const soundObject = new Audio.Sound(); await soundObject.loadAsync({ uri: originalUri }); await soundObject.recordAsync({ uri: convertedUri, format: Audio.RECORDING_FORMAT_MP3, }); await soundObject.stopAsync(); await soundObject.unloadAsync(); // 后续使用convertedUri上传
4. 表单字段名匹配问题
后端代码中通过context.Request.Form["expectedText"]获取字段值,需确保前端formData.append('expectedText', 'Hello')的字段名与后端完全一致(大小写敏感)。
验证步骤
- 优先移除手动设置的
Content-Type头,测试是否解决问题 - 若未解决,调整文件URI的跨平台格式
- 最后检查录制文件的实际格式是否为MP3
内容的提问来源于stack exchange,提问作者Công Nguyễn

