如何在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
相关产品推荐
相关产品推荐

