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

React Native上传multipart form-data至Heroku部署的Node/Express服务器报500错误

排查React Native POST图片到Express服务器500错误的问题

我帮你梳理下几个关键的问题点,这些应该就是导致请求失败的核心原因:

1. Multer字段名完全不匹配(最关键问题)

你在React Native里用formData.append("photo", ...)上传的字段名是photo,但Express路由里配置的是multer.single("image")——两者字段名完全不一致!Multer找不到对应字段的文件时,会直接卡在预处理阶段,根本进不到你的路由处理函数,所以你看不到console.log("post")的输出,最终返回500错误。

2. Axios请求参数传递错误

看你的React Native代码,axios.post的调用逻辑有问题:

axios.post("https://prezzi-api.herokuapp.com/upload", formData, options)

这里options里又写了body: formData,相当于把formData重复传了两次。Axios的POST方法参数规则是axios.post(url, data, config),第二个参数本身就是请求体,所以options里的body完全多余,还会造成参数冲突。

3. 手动设置Content-Type导致解析失败

当上传FormData时,React Native的请求引擎会自动生成带boundary的Content-Type头(比如multipart/form-data; boundary=----WebKitFormBoundaryXYZ),但你手动设置了"Content-Type": "multipart/form-data",缺少了关键的boundary标识,服务器无法正确解析表单数据,这也是请求失败的重要原因。


修复后的代码示例

React Native端修改:

upload = async uri => {
  const formData = new FormData();
  // 字段名改成和后端匹配的"image",建议给文件名加上后缀帮助服务器识别类型
  formData.append("image", { 
    uri, 
    name: `photo.jpg`,  
    type: `image/jpg` 
  });

  try {
    const response = await axios.post(
      "https://prezzi-api.herokuapp.com/upload", 
      formData,
      // 不需要手动设置Content-Type,axios会自动处理
      { headers: { Accept: "application/json" } }
    );
    console.warn(response.data);
  } catch (error) {
    console.warn("error uploading to OCR", error);
  }
};

Express端优化(增加错误捕获):

先确保multer的字段名和前端一致,再加上multer的错误捕获中间件,方便排查问题:

const multer = require('multer');
// 对应你的GCS上传逻辑,用内存存储文件
const storage = multer.memoryStorage(); 
const upload = multer({ storage: storage });

router.post(
  "/", 
  // 字段名和前端统一为"image"
  upload.single("image"), 
  // 新增multer错误捕获中间件
  (err, req, res, next) => {
    if (err instanceof multer.MulterError) {
      console.error("Multer上传错误:", err);
      return res.status(400).send("文件上传错误: " + err.message);
    } else if (err) {
      console.error("未知上传错误:", err);
      return res.status(500).send("上传失败");
    }
    next();
  },
  gcsMiddlewares.sendUploadToGCS, 
  (req, res, next) => {
    console.log("post");
    if (req.file && req.file.gcsUrl) {
      return res.send(req.file.gcsUrl);
    }
    return res.status(500).send("Unable to upload");
  }
);

额外排查建议

  1. 查看Heroku服务器日志:在终端执行heroku logs --tail,可以看到服务器端的详细错误栈,帮你进一步定位是multer的问题还是GCS上传环节的问题。
  2. 确认React Native的uri格式:iOS和Android的文件uri格式不同(iOS是file:///...,Android可能是content://...),如果是Android的content uri,可能需要先转换为file uri再上传,可以用react-native-fs库辅助处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:04:44