如何通过Multer处理Postman Form-Data中对象数组内的ServiceIcon上传并存储路径
解决方案
一、Postman 请求格式调整
因为是 Form-Data 提交,无法直接将文件嵌套在 JSON 结构里,需要拆分字段提交:
- 添加
data字段,类型选「text」,值为原始 JSON(注意把serviceIcon设为空字符串占位):{"step":"services","servicesDescription": [{ "serviceTitle":"aaaaaaaaaaaaaaaaaaa", "serviceIcon": "" },{ "serviceTitle":"bbbbbbbbbbbbbbbbbb", "serviceIcon": "" }],"_id":"63b7c15f06501c1ea0729f24"} - 分别添加文件字段,命名规则为
servicesDescription[0].serviceIcon、servicesDescription[1].serviceIcon,每个字段对应选择要上传的abc.jpg文件。
二、后端 Node.js + Multer 实现代码
1. 安装依赖
先安装所需包:
npm install express multer
2. 配置 Multer 存储规则
const express = require('express'); const multer = require('multer'); const fs = require('fs'); const app = express(); // 配置文件存储路径与文件名 const storage = multer.diskStorage({ destination: (req, file, cb) => { // 自动创建 uploads 目录(不存在时) const uploadDir = './uploads'; if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir, { recursive: true }); } cb(null, uploadDir); }, filename: (req, file, cb) => { // 生成唯一文件名,避免文件覆盖 const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); const ext = file.originalname.split('.').pop(); cb(null, `${file.fieldname}-${uniqueSuffix}.${ext}`); } }); const upload = multer({ storage: storage });
3. 处理上传的核心路由
使用 upload.fields() 指定需要处理的文件字段,再将上传后的路径替换回原 JSON 结构:
app.post('/upload-services', upload.fields([ { name: 'servicesDescription[0].serviceIcon', maxCount: 1 }, { name: 'servicesDescription[1].serviceIcon', maxCount: 1 } ]), (req, res) => { try { // 解析 Form-Data 中的 JSON 数据 const formData = JSON.parse(req.body.data); const servicesList = formData.servicesDescription; // 遍历替换每个 serviceIcon 的路径 servicesList.forEach((item, index) => { const fileKey = `servicesDescription[${index}].serviceIcon`; if (req.files[fileKey]) { // 可根据需求调整路径(比如绝对路径或域名+路径) item.serviceIcon = `/uploads/${req.files[fileKey][0].filename}`; } }); // 此时 formData 已更新为带上传路径的结构,可直接存入数据库或返回 console.log('处理完成的数据:', formData); res.status(200).json({ success: true, data: formData }); } catch (err) { res.status(500).json({ success: false, message: err.message }); } }); app.listen(3000, () => { console.log('服务器运行在 http://localhost:3000'); });
三、动态适配数组长度(可选)
如果 servicesDescription 的元素数量不固定,可以动态生成文件字段列表:
app.post('/upload-dynamic', (req, res) => { // 先解析 JSON 获取数组长度 const tempData = JSON.parse(req.body.data); const fileFields = tempData.servicesDescription.map((_, idx) => ({ name: `servicesDescription[${idx}].serviceIcon`, maxCount: 1 })); // 动态处理文件上传 upload.fields(fileFields)(req, res, (err) => { if (err) return res.status(500).json({ success: false, message: err.message }); try { const formData = JSON.parse(req.body.data); formData.servicesDescription.forEach((item, idx) => { const fileKey = `servicesDescription[${idx}].serviceIcon`; if (req.files[fileKey]) { item.serviceIcon = `/uploads/${req.files[fileKey][0].filename}`; } }); res.status(200).json({ success: true, data: formData }); } catch (err) { res.status(500).json({ success: false, message: err.message }); } }); });
内容的提问来源于stack exchange,提问作者SUBHAJIT CHAKRABORTY
相关产品推荐
相关产品推荐

