React Native调用API报错,React Web端正常,请求排查代码问题
嘿,我帮你对比了Web端和React Native端的代码,发现几个可能导致报错的核心差异,咱们一个个来解决:
1. JSON数据没有转成Blob就传入FormData
你在Web端是把JSON字符串转成application/json类型的Blob后再append到FormData,但RN端直接传了纯JSON字符串。后端期望的是一个符合格式的Blob对象,纯字符串会导致它解析filterData时失败。
修正方式:和Web端保持一致,把JSON转成Blob,并且在append时指定文件名(RN的FormData需要这个参数):
const jsonFilter = JSON.stringify(filterData); const blobFilter = new Blob([jsonFilter], { type: 'application/json' }); data.append('filterData', blobFilter, 'filterData.json'); // 第三个参数是文件名,帮助后端识别
2. 文件上传的格式不符合RN FormData要求
Web端的selectedFile是标准的File对象,但RN中从相机/相册获取的文件一般是URI格式,直接append会导致后端无法识别。你需要把文件包装成RN FormData支持的格式,包含uri、name和type三个属性。
修正方式:假设你的selectedFile来自react-native-image-picker这类库,调整成这样:
if (selectedFile) { data.append('filterFile', { uri: selectedFile.uri, name: selectedFile.fileName || 'uploaded-file.txt', // 自定义文件名,或者用返回的fileName type: selectedFile.type || 'text/plain', // 根据文件类型设置对应的MIME类型 }); }
3. 手动设置Content-Type: multipart/mixed干扰了自动处理
在Web端手动设置这个头没问题,但RN中的axios会自动生成包含boundary(分隔符)的multipart/form-data头——这个boundary是后端分割FormData内容的关键。手动设置multipart/mixed会覆盖自动生成的头,导致后端无法正确解析各个字段。
修正方式:直接去掉手动设置的Content-Type,让axios自动处理:
await axios.post('https://capi.beebl.io/filter', data, { headers: { // 这里只加必要的头,比如Authorization(如果需要的话) // 'Authorization': `Bearer ${yourToken}`, }, })
完整修正后的代码
const filterData = { content: '', filterLimit: 1000, sorting: 'NATURAL', contractionOption: 'LEAVE_CONTRACTION', contentId: '', url: 'https://stackoverflow.com/questions/37552973/get-the-time-zone-with-react-native', }; const data = new FormData(); // 处理JSON数据为Blob const jsonFilter = JSON.stringify(filterData); const blobFilter = new Blob([jsonFilter], { type: 'application/json' }); data.append('filterData', blobFilter, 'filterData.json'); // 处理文件上传 if (selectedFile) { data.append('filterFile', { uri: selectedFile.uri, name: selectedFile.fileName || 'uploaded-file', type: selectedFile.type || 'application/octet-stream', }); } try { const res = await axios.post('https://capi.beebl.io/filter', data, { // 仅添加必要的请求头,比如token // headers: { 'Authorization': `Bearer ${yourToken}` } }); console.log('请求成功:', res); } catch (err) { console.error('请求失败:', err.response?.data || err.message); }
另外补充一点:如果你的RN版本比较旧,原生Blob支持可能有问题,这时候可以考虑用react-native-blob-util这类库来替代原生Blob,但新版RN已经很好支持原生Blob了,优先用原生的就行。
内容的提问来源于stack exchange,提问作者Abdul Kabir

