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

Expo v48及以上版本如何将本地图片添加到FormData?

Expo v48/v49 下 FormData 上传图片问题解决

问题背景

Expo v47 及对应 React Native、TypeScript 版本中,FormData.append 的类型定义宽松,允许传入任意类型值:

FormData.append(name: string, value: any): void

当时可直接通过自定义图片对象完成上传:

const image = {
  uri: x.uri,
  name: x.name,
  size: x.size,
  type: 'image/jpeg',
}

const formDataBody = new FormData()
formDataBody.append('data', image)

升级到 Expo v48/v49 后,FormData.append 的类型定义收紧,仅接受字符串或 Blob 类型:

FormData.append(name: string, value: string | Blob): void

尝试过的方法及遇到的问题

  1. 转 base64 再生成 File 对象上传,触发网络错误:
try {
  base64String = await FileSystem.readAsStringAsync(image.uri, { encoding: 'base64' })
} catch (error: any) {
  // ...
}

const binaryData = decode(base64String)

const buffer = new Uint8Array(binaryData.length)
for (let i = 0; i < binaryData.length; i++) {
  buffer[i] = binaryData.charCodeAt(i)
}

const file = new File([binaryData], 'data', { type: 'image/jpeg' })

formDataBody.append('data', file)
  1. 尝试使用 react-native-fs 模块,出现启动错误:
ERROR  Invariant Violation: "main" has not been registered. This can happen if:
Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called., js engine: hermes

解决方案

方案1:通过 Expo FileSystem 获取 Blob 上传

这是最可靠的原生兼容方案,无需复杂转换:

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

// 从本地URI获取Blob对象
const getImageBlob = async (uri: string) => {
  const response = await fetch(uri);
  return response.blob();
};

// 构建FormData
const formDataBody = new FormData();
const blob = await getImageBlob(image.uri);
// 第三个参数指定文件名,确保服务端能正确识别
formDataBody.append('data', blob, image.name);

原理:React Native 支持通过 fetch 本地文件 URI 直接获取 Blob,避免 base64 转换带来的编码错误和性能损耗。

方案2:类型断言绕过TS检查(仅兼容旧服务端)

如果后端仍支持原上传格式,可通过类型断言绕过 TypeScript 的类型限制:

const image = {
  uri: x.uri,
  name: x.name,
  type: 'image/jpeg',
};

const formDataBody = new FormData();
// 用类型断言绕过TS类型检查
formDataBody.append('data', image as unknown as Blob);

注意:此方案依赖 RN 运行时的 FormData 实现仍支持自定义对象,部分新版本可能已移除该支持,需自行验证。

解决 react-native-fs 启动错误

若必须使用该模块:

  • 确保 Metro 服务在项目根目录启动,执行 npx expo start --clear 清除缓存后重启
  • 确认 react-native-fs 版本与 Expo v48/v49 兼容,优先使用官方的 expo-file-system 替代第三方模块,减少兼容性问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:55:07