Express JS接口req.body返回Buffer 无法解析FormData上传参数
问题根因
- 你拿到原始Buffer的原因很简单:Express自带的
express.json()、express.urlencoded()中间件只处理JSON和表单urlencoded格式的请求,完全不支持multipart/form-data类型的上传请求,所以不会自动把请求体解析成结构化对象,只会返回原始二进制Buffer。 - 你用multer报
Cannot read properties of undefined (reading 'apply'),是multer中间件的写法错误:大概率是直接把multer实例传给了路由当中间件,没有调用multer提供的single/array/fields方法生成合法的中间件函数,Express执行的时候找不到可执行的函数就会报这个错。
修复步骤
1. 安装依赖
先确认multer已经正确安装到项目依赖中,执行命令:
npm install multer
2. 后端接口正确配置multer中间件
不要把multer作为全局中间件挂载,在需要处理文件上传的路由上单独引用即可,参考以下实现:
const express = require('express'); const multer = require('multer'); const app = express(); // 配置multer使用内存存储,直接拿到文件Buffer,适配后续上传Cloud Storage的场景,不需要写本地磁盘 const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 100 * 1024 * 1024 // 单文件大小限制根据业务调整,示例为100MB } }); // 注意:必须调用upload.fields生成中间件,直接传upload实例就会触发你之前遇到的apply报错 app.post("/categories", upload.fields([ { name: 'thumbnail', maxCount: 1 }, { name: 'video', maxCount: 1 } ]), async (req, res) => { // req.body就是解析完成的结构化文本字段,可以直接存入FireStore console.log(`req.body: ${JSON.stringify(req.body)}`) console.log(`req.body.title: ${req.body.title}`) // 上传的文件存储在req.files中,和字段名对应 console.log(`封面文件信息:`, req.files.thumbnail?.[0]) console.log(`视频文件信息:`, req.files.video?.[0]) // 后续业务逻辑:req.body的文本字段存FireStore,req.files里的文件Buffer上传到Cloud Storage即可 res.json({ code: 0, msg: 'success' }) });
3. 调整前端Axios配置
不要手动设置Content-Type: multipart/form-data请求头,multipart格式需要自动生成随机boundary分隔符才能被后端正确解析,手动写死头会导致boundary丢失,修改后前端代码:
methods: { async createCategory() { const formData = new window.FormData(); formData.set("title", this.category.title); formData.set("description", this.category.description); formData.set("thumbnail", this.thumbnail); formData.set("video", this.video); // 移除手动配置的headers,让Axios自动识别FormData生成带正确boundary的请求头 await this.axios.post("clothing/v1/categories/", formData); } }
避坑说明
- 不要用
app.use(upload.array())这类方式全局挂载multer,容易和普通JSON接口的解析逻辑冲突 - 除了内存存储,multer也支持磁盘存储,但如果后续要把文件传到Cloud Storage,内存存储省去了本地文件读写的步骤,效率更高
- 如果要加文件类型校验,可以在multer配置里加
fileFilter字段做白名单过滤
内容的提问来源于stack exchange,提问作者Dean Christian Armada
相关产品推荐
相关产品推荐

