You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native + Expo环境下Axios发送Multipart/Formdata报415(Unsupported media type)错误求助

React Native + Expo环境下Axios发送Multipart/Formdata报415(Unsupported media type)错误求助

我完全懂你遇到这个415错误的崩溃感——试遍了各种方法都不管用,之前用Fetch还好好的,后端又确认没问题,这种卡壳真的特别磨人😮‍💨 结合你的代码和React Native + Expo的环境特性,我整理了几个针对性的解决方案,你可以逐一尝试:


一、先排查Axios自动处理Content-Type的问题

Axios在发送FormData时,会自动设置正确的multipart/form-data请求头并生成boundary,但如果手动设置了Content-Type或者全局头干扰了这个逻辑,就会导致后端无法解析请求。

代码修改点:

在postScan和postRegister函数中,确保不手动设置Content-Type,并强制删除可能存在的全局配置:

// 以postScan函数为例,registerGuest里的postRegister同理修改
const postScan = async () => {
  const token = await AsyncStorage.getItem("access_token");
  try {
    const res = await API.post("/scan-guest/", data, {
      headers: {
        Authorization: `Bearer ${token}`,
        // 绝对不要手动设置Content-Type!!!
      },
      transformRequest: (data, headers) => {
        // 删除全局可能存在的Content-Type,让Axios自动处理
        delete headers.common['Content-Type'];
        return data;
      }
    });
    // 后续逻辑保持不变
  } catch (err: any) {
    // 错误处理逻辑保持不变
  }
};

二、修正React Native中FormData的文件构造逻辑

React Native的FormData和Web端实现有差异,特别是Expo相机返回的图片URI(Android可能是content://开头,iOS是file://),需要确保文件项格式完全符合要求。

步骤1:引入Expo File System处理URI

先安装依赖(如果没装的话):

npx expo install expo-file-system

步骤2:修改图片URI的处理逻辑

在takeAndScanPhoto和registerGuest中,先把相机返回的URI转换成标准的file://格式:

import * as FileSystem from 'expo-file-system';

// 以takeAndScanPhoto为例:
const takeAndScanPhoto = async () => {
  if (!cameraRef.current) return;
  // 让相机直接把图片存在缓存目录,确保返回file://格式的URI
  const photo = await cameraRef.current.takePictureAsync({ 
    quality: 0.8, 
    base64: false,
    uri: `${FileSystem.cacheDirectory}scan_${Date.now()}.jpg`
  });
  
  // 验证URI有效性
  const fileInfo = await FileSystem.getInfoAsync(photo.uri);
  const validFileUri = fileInfo.uri;

  setPhotoUri(validFileUri);
  setScanned(true);

  const data = new FormData();
  data.append("img", {
    uri: validFileUri,
    name: getFileName(validFileUri),
    type: getMimeType(validFileUri),
  } as any);
  
  // 后续postScan逻辑保持不变
};

三、尝试让Axios使用Fetch适配器

既然你之前用Fetch是正常的,那可以让Axios复用Fetch的请求逻辑,避免XMLHttpRequest适配器在React Native中处理Multipart请求的兼容性问题:

步骤1:安装Fetch适配器

npm install @vespaiach/axios-fetch-adapter

步骤2:修改api.js配置

import axios from "axios";
import fetchAdapter from '@vespaiach/axios-fetch-adapter';

const API = axios.create({
  baseURL: 'http://127.0.0.1:8000/myapi/',
  // 强制Axios使用Fetch发送请求,复用已验证的兼容逻辑
  adapter: fetchAdapter
});

export default API;

这个方法相当于让Axios“伪装”成Fetch发送请求,成本最低,大概率能直接解决问题。


四、最后验证:用Fetch对比测试

如果上面的方法都不行,可以暂时把Axios换回Fetch(和你之前的工作版本对比),确认请求格式是否正确:

// 替换postScan里的Axios请求为Fetch
const postScan = async () => {
  const token = await AsyncStorage.getItem("access_token");
  const response = await fetch('http://127.0.0.1:8000/myapi/scan-guest/', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
      // Fetch会自动处理FormData的Content-Type,不要手动设置
    },
    body: data
  });
  
  if (response.ok) {
    const resData = await response.json();
    // 后续逻辑保持不变
  } else {
    // 错误处理保持不变
  }
};

如果Fetch能正常工作,那问题肯定出在Axios的配置或FormData处理上,回到前三个方案排查即可。


总结

最可能的原因是:

  1. Axios的自动Content-Type配置被干扰,导致请求头没有正确携带boundary
  2. React Native的FormData对Expo相机返回的URI格式不兼容
  3. Axios默认的XMLHttpRequest适配器在React Native中处理Multipart请求的bug

优先尝试方案三(Fetch适配器),因为它直接复用了你已经验证过的兼容逻辑,成本最低;如果不行再试方案一和方案二。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 08:09:31