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

React Native + Expo 上传图片时遭遇[Error: Unsupported FormDataPart implementation]错误的问题排查求助

React Native + Expo 上传图片时遭遇[Error: Unsupported FormDataPart implementation]错误的问题排查求助

大家好,我现在在用 React Native + Expo 开发项目,尝试通过 FormData 结合 fetch 上传图片,选图功能用的是 expo-image-picker。但每次触发上传都会抛出 [Error: Unsupported FormDataPart implementation] 这个错误,我翻了好多次代码都没找到问题所在,麻烦各位帮我排查一下!

我的实现逻辑与关键代码

我先处理了相册/相机的权限申请,选到图片后把图片信息包装成对象塞进 FormData,再通过封装的请求函数发送。以下是核心代码片段:

1. 权限申请与选图逻辑

const requestPermissions = async () => {
  const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
  if (status !== 'granted') {
    Alert.alert('Permissions Required', 'We need permission to access your photo library.', [
      { text: 'OK' },
    ]);
    return false;
  }
  return true;
};

const pickImageFromGallery = async () => {
  const hasPermission = await requestPermissions();
  if (!hasPermission) return;
  try {
    const image = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: 'images',
      allowsEditing: true,
      aspect: [1, 1],
      quality: 0.8,
    });
    if (!image.canceled && image.assets && image.assets.length > 0) {
      const asset = image.assets[0];
      await onUploadImage(asset);
    }
  } catch (error) {
    Alert.alert('Errore', error);
  }
};

const takePhoto = async () => {
  const { status } = await ImagePicker.requestCameraPermissionsAsync();
  if (status !== 'granted') {
    Alert.alert('Permissions Required', 'We need permission to access your camera.', [
      { text: 'OK' },
    ]);
    return;
  }
  try {
    const image = await ImagePicker.launchCameraAsync({
      allowsEditing: true,
      aspect: [1, 1],
      quality: 0.8,
    });
    if (!image.canceled && image.assets && image.assets.length > 0) {
      const asset = image.assets[0];
      await onUploadImage(asset);
    }
  } catch (error) {
    Alert.alert('Errore', error);
  }
};

2. 图片上传核心逻辑

const onUploadImage = async asset => {
  console.log('file', asset);
  const fileToUpload = {
    uri: asset.uri,
    name: asset.fileName ?? `image_${Date.now()}.jpg`,
    type: asset.mimeType ?? 'image/jpeg',
  };

  const formData = new FormData();
  formData.append('file', fileToUpload);

  try {
    setIsLoading(true);
    const response = await postAuthenticatedAPI({
      token: user?.access_token,
      isChatEndpoint: false,
      formData: true,
      endpoint: UPLOAD_FILE,
      payload: formData,
    });
    console.log('res', response);
    if (response) {
      setImageData(prev => ({
        ...prev,
        id: `img_${Date.now()}`,
        url: asset.uri,
      }));
      onImageChange('cover_image', response?.file || asset.uri);
    }
  } catch (error) {
    setModalConfig({
      title: 'Error',
      subtitle: error?.message || 'Error fetch',
      type: 'error',
    });
    setShowModal(true);
  } finally {
    setIsLoading(false);
  }
};

3. 封装的请求函数

export const postAuthenticatedAPI = async ({
  payload,
  endpoint,
  token,
  formData = false,
  isChatEndpoint = false,
}) => {
  const baseUrl = isChatEndpoint ? process.env.EXPO_PUBLIC_BASE_CHAT : process.env.EXPO_PUBLIC_BASE_URL;
  const url = baseUrl + endpoint;
  try {
    const headersWithFormData = {
      Authorization: `Bearer ${token}`,
    };
    const withoutFormDataHeader = {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    };
    const response = await fetch(url, {
      method: 'POST',
      headers: formData ? headersWithFormData : withoutFormDataHeader,
      body: formData ? payload : JSON.stringify(payload),
    });
    if (response.status === 200 || response.status === 201) {
      return await response.json();
    } else throw new Error('Server error');
  } catch (e) {
    const error = new Error(e?.message || 'Something went wrong');
    error.info = e.info || null;
    error.status = e.status || null;
    throw error;
  }
};

我已经自查过的内容

  • 图片的 uri、name、type 字段都有正确赋值,打印 fileToUpload 结果看起来完全正常
  • 传 FormData 时没有手动设置 Content-Type,因为查资料说浏览器会自动添加带边界的 multipart/form-data 头
  • 相册/相机权限都能正常申请通过,选图后也能拿到完整的 asset 信息

有没有朋友遇到过类似的问题?或者能帮我指出代码里的疏漏吗?非常感谢!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 03:10:36