Node.js服务端如何读取前端上传的包含文件的FormData数据
问题原因
- Express 自带的
body-parser中间件仅支持解析application/json和application/x-www-form-urlencoded类型的请求,无法处理multipart/form-data格式的 FormData 请求,因此读取不到你提交的字段和文件。 - 前端 fetch 配置中手动指定了
Content-Type: multipart/form-data,会丢失表单分割所需的 boundary 标识,也会导致服务端无法正常解析请求体。
解决步骤
第一步:修改前端代码
删掉 fetch 配置里 headers 中的 'Content-Type': "multipart/form-data" 配置项,浏览器发送 FormData 时会自动添加带正确 boundary 的 Content-Type 头,不需要手动设置。
修改后对应代码如下:
fetch('http://localhost:3000/up', { method: 'POST', body: formData, mode: "cors", // 移除手动设置的Content-Type头 })
第二步:服务端配置 multer 中间件
multer 是 Express 生态专门用于处理 multipart/form-data 请求的中间件,支持同时解析文本字段和上传文件。
1. 安装依赖
npm install multer
2. 调整服务端完整代码
const express = require ('express') const bodyParser = require ('body-parser') const app = express() const api = express.Router() const cors = require('cors') // 引入multer const multer = require('multer') // 配置multer:如果需要直接存文件到本地磁盘可替换为diskStorage配置,见下方补充说明 const storage = multer.memoryStorage() // 字段名要和前端formData.append的文件字段名一致,这里你前端写的是photo const upload = multer({ storage: storage }) app.use(bodyParser.urlencoded({ extended:false})) app.use(bodyParser.json()) app.use(cors({ origin: true })); // 接口添加multer中间件,single表示只接收1个文件,参数为前端定义的文件字段名 api.post('/up', upload.single('photo'), (req, res) =>{ // 读取文本参数 console.log('a1参数值:', req.body.a1) console.log('b1参数值:', req.body.b1) // 读取上传的文件信息 console.log('文件原名称:', req.file.originalname) console.log('文件大小:', req.file.size) // 内存存储模式下req.file.buffer为文件二进制内容,可自行写入磁盘 // 返回前端需要的字段 res.json({ filename: '自定义保存的文件名', originalname: req.file.originalname, message: '上传成功' }) }) // 挂载路由,你原代码漏了这行会导致接口404 app.use(api) const PORT = 3000; // 你原代码的config.port未定义,直接用PORT变量即可 app.listen(PORT, ()=>{ console.log(`Server running on port: ${PORT}`) })
补充:文件直接存本地磁盘的配置
如果需要把上传的文件直接保存到本地磁盘,可以把 multer 的 storage 配置替换为如下内容:
const storage = multer.diskStorage({ destination: function (req, file, cb) { // 需要先手动在项目根目录创建uploads文件夹用于存文件 cb(null, './uploads/') }, filename: function (req, file, cb) { // 自定义保存的文件名,用时间戳避免重名 const saveName = Date.now() + '-' + file.originalname cb(null, saveName) } }) const upload = multer({ storage: storage })
该配置下 req.file.filename 就是文件保存在本地的名称,可以直接返回给前端拼接访问路径。
内容的提问来源于stack exchange,提问作者rottenCoderSo
相关产品推荐
相关产品推荐

