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

如何在Express服务器中正确保存React客户端上传的图片?

解决React上传FormData到Express后文件保存格式错误的问题

问题出在Express默认的body-parser无法正确解析multipart/form-data类型的请求,你直接用body-parser解析后的buffer写入文件,拿到的不是完整的文件二进制数据,自然会导致格式损坏。正确的做法是使用专门处理文件上传的中间件,比如multer或express-fileupload。

方案一:使用multer(推荐,功能更完善)

1. 安装依赖

npm install multer

2. 服务端配置

const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');

const app = express();

// 配置文件存储规则:路径+文件名
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    // 确保上传目录存在,不存在则创建
    const uploadDir = './uploads';
    if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir);
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    // 用时间戳+原文件名避免重名
    cb(null, `${Date.now()}-${file.originalname}`);
  }
});

const upload = multer({ storage });

// 处理单文件上传的接口,'file'对应客户端FormData的键名
app.post('/upload', upload.single('file'), (req, res) => {
  // 文件已自动保存到指定目录,req.file包含文件详情
  res.json({
    success: true,
    filePath: `/uploads/${req.file.filename}`
  });
});

app.listen(3000, () => console.log('服务器运行在3000端口'));

3. React客户端代码

import axios from 'axios';

const handleFileUpload = async (file) => {
  const formData = new FormData();
  // 这里的'file'必须和服务端upload.single('file')的参数一致
  formData.append('file', file);

  try {
    await axios.post('http://localhost:3000/upload', formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    });
    console.log('文件上传并保存成功');
  } catch (err) {
    console.error('上传失败:', err);
  }
};

方案二:使用express-fileupload(轻量易上手)

1. 安装依赖

npm install express-fileupload

2. 服务端配置

const express = require('express');
const fileUpload = require('express-fileupload');
const fs = require('fs');
const path = require('path');

const app = express();

// 启用文件上传中间件
app.use(fileUpload());

app.post('/upload', (req, res) => {
  if (!req.files?.file) {
    return res.status(400).json({ success: false, msg: '未选择文件' });
  }

  const uploadedFile = req.files.file;
  const uploadDir = './uploads';
  if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir);
  const savePath = path.join(uploadDir, `${Date.now()}-${uploadedFile.name}`);

  // 移动文件到指定路径
  uploadedFile.mv(savePath, (err) => {
    if (err) return res.status(500).json({ success: false, msg: '保存失败' });
    res.json({
      success: true,
      filePath: `/uploads/${path.basename(savePath)}`
    });
  });
});

app.listen(3000, () => console.log('服务器运行在3000端口'));

客户端代码和方案一完全一致,无需修改。

注意事项

  • 确保服务器的uploads目录有读写权限,避免文件保存失败
  • 如需限制文件类型、大小,可在中间件配置中添加对应规则(比如multer的fileFilter、express-fileupload的limits)
  • 彻底放弃用body-parser处理文件上传请求,它仅支持application/json、application/x-www-form-urlencoded这类格式

内容的提问来源于stack exchange,提问作者Juan Esteban Villegas Arias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:40:33