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

React Native调用Google Drive API上传文件遇格式错误求助

解决React Native向Google Drive API发送multipart/form-data的"Malformed multipart body"错误

常见问题原因及解决方案

1. Metadata字段的FormData构造方式错误

React Native的FormData.append方法对JSON类型字段的处理逻辑和浏览器/Postman存在差异,直接传递JSON字符串并指定type无法生成符合要求的multipart结构。正确做法是将JSON数据包装成Blob,并指定对应文件名(模拟Postman中上传JSON文件的行为):

const metadata = {
  name: fileName,
  mimeType: fileMimeType,
  description: fileDescription,
  parents: [GOOGLE_DRIVE_FOLDER_ID]
};
// 将metadata转为Blob并指定文件名
formData.append("metadata", new Blob([JSON.stringify(metadata)], { type: 'application/json' }), 'metadata.json');

2. 文件URI格式兼容问题

React Native中iOS和Android的文件URI格式存在差异:

  • iOS的URI通常以file://开头,需要移除该前缀
  • Android的URI可能是content://格式,需确保权限正常或转换为标准文件路径

修改文件URI处理逻辑:

import { Platform } from 'react-native';

// 处理跨平台URI格式
const fileUri = Platform.OS === 'ios' 
  ? file.assets[0].uri.replace('file://', '') 
  : file.assets[0].uri;

formData.append('file', {
  uri: fileUri,
  type: fileMimeType,
  name: fileName,
});

3. 避免手动设置Content-Type头

React Native的fetch会自动为FormData类型请求生成包含正确boundary的Content-Type头,手动设置反而会导致boundary不匹配,引发格式错误。确保请求头中不要添加Content-Type: multipart/form-data。

修改后的完整代码

import { Platform } from 'react-native';

export const uploadToGoogleDrive = async (data) => {
  try {
    const accessToken = await signInWithGoogle();
    const fileName = data.title;
    const fileDescription = data.description;
    const file = data.file;
    const fileMimeType = file.assets[0].mimeType;

    const formData = new FormData();

    // 正确构造metadata部分
    const metadata = {
      name: fileName,
      mimeType: fileMimeType,
      description: fileDescription,
      parents: [GOOGLE_DRIVE_FOLDER_ID]
    };
    formData.append("metadata", new Blob([JSON.stringify(metadata)], { type: 'application/json' }), 'metadata.json');

    // 处理跨平台文件URI
    const fileUri = Platform.OS === 'ios' 
      ? file.assets[0].uri.replace('file://', '') 
      : file.assets[0].uri;

    formData.append('file', {
      uri: fileUri,
      type: fileMimeType,
      name: fileName,
    });

    const response = await fetch(`${GOOGLE_DRIVE_ENDPOINT}/files?uploadType=multipart`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        // 禁止手动设置Content-Type
      },
      body: formData,
    });

    if (!response.ok) {
      const errorText = await response.json();
      console.log("Detailed Error:", errorText);
      throw new Error(`Error uploading file: ${response.statusText}, details: ${JSON.stringify(errorText)}`);
    }

    return await response.json();

  } catch (error) {
    console.error("Upload error:", error);
    if (error.response) {
      console.error("Response data:", error.response.data);
    } else if (error.request) {
      console.error("Request details:", error.request);
    } else {
      console.error("Error:", error.message);
    }
    throw error;
  }
};

替代方案

如果上述方法仍无法解决问题,可尝试以下方案:

  • 使用rn-fetch-blob库:该库对multipart请求的处理更接近原生,兼容性更好,适合复杂文件上传场景
  • 切换为Google Drive API的resumable上传类型:分块上传可规避multipart格式问题,同时支持大文件断点续传

内容的提问来源于stack exchange,提问作者Alexa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 07:32:11