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

Expo Go无法上传Base64编码图片:安卓正常iOS端异常

问题排查与解决方案

核心矛盾:前端发送格式与后端接收方式不匹配

upload.single('photo')是multer专门处理multipart/form-data格式的文件上传的中间件,它不会解析普通字符串字段(包括Base64格式的字符串)。Android上能正常工作大概率是偶然情况,iOS的Expo Go在FormData处理上更严格,直接暴露了这个格式不匹配的问题。

具体排查步骤与修复方案

1. 修正前端请求格式(最可能解决问题)

如果直接把Base64字符串作为普通字段传,multer根本识别不了。正确做法是把Base64转成Blob,再作为文件字段添加到FormData里:

async function logPicture(base64String) {
  // 先去掉Base64前缀(比如data:image/jpeg;base64,)
  const pureBase64 = base64String.replace(/^data:image\/\w+;base64,/, '');
  // 把Base64转成Blob
  const byteChars = atob(pureBase64);
  const byteNumbers = new Array(byteChars.length);
  for (let i = 0; i < byteChars.length; i++) {
    byteNumbers[i] = byteChars.charCodeAt(i);
  }
  const byteArray = new Uint8Array(byteNumbers);
  const blob = new Blob([byteArray], { type: 'image/jpeg' }); // 按实际图片类型调整

  const formData = new FormData();
  formData.append('photo', blob, 'captured.jpg'); // 第三个参数是文件名,可选
  formData.append('local', '你的local参数值'); // 保留原有参数

  try {
    const res = await fetch('你的后端接口地址', {
      method: 'POST',
      body: formData,
      // 注意:iOS上别手动加Content-Type,浏览器会自动带boundary参数,手动加会导致multer识别失败
    });
    const result = await res.json();
    console.log('上传结果:', result);
  } catch (err) {
    console.error('上传失败:', err);
  }
}

2. 用Expo原生文件系统处理(兼容iOS更稳定)

如果上面的Blob方式还是有问题,试试用expo-file-system把Base64转成本地临时文件再上传:

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

async function logPicture(base64String) {
  const tempPath = `${FileSystem.cacheDirectory}captured.jpg`;
  // 把Base64写入临时文件
  await FileSystem.writeAsStringAsync(
    tempPath,
    base64String.replace(/^data:image\/\w+;base64,/, ''),
    { encoding: FileSystem.EncodingType.Base64 }
  );

  const formData = new FormData();
  formData.append('photo', {
    uri: tempPath,
    name: 'captured.jpg',
    type: 'image/jpeg'
  });
  formData.append('local', '你的local参数值');

  try {
    const res = await fetch('你的后端接口地址', {
      method: 'POST',
      body: formData,
      headers: { 'Accept': 'application/json' }
    });
    const result = await res.json();
    console.log('上传结果:', result);
  } catch (err) {
    console.error('上传失败:', err);
  }
}

3. 后端加日志验证请求

在后端multer中间件前加日志,确认请求格式是否正确:

app.post('/upload', (req, res, next) => {
  console.log('请求Content-Type:', req.headers['content-type']);
  next();
}, upload.single('photo'), (req, res) => {
  console.log('收到的文件:', req.file);
  console.log('收到的local参数:', req.body.local);
  // 后续保存逻辑
});

如果Content-Type里没有boundary=xxx,说明前端请求格式错误,必须调整FormData的发送方式。

4. 检查iOS权限配置

确保Expo应用在iOS上申请了必要权限,虽然拍照成功,但权限不足可能影响文件处理。在app.json里添加:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSCameraUsageDescription": "需要访问相机拍照",
        "NSPhotoLibraryAddUsageDescription": "需要访问相册保存照片"
      }
    }
  }
}

总结

本质问题是前端发送的Base64字符串和后端multer期望的文件上传格式不匹配,iOS的Expo Go没像Android那样“兼容”错误格式。通过把Base64转成Blob或临时文件,用标准multipart/form-data格式发送,就能解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 15:56:16