问题描述
我在我的 React 应用程序中发送了一个请求,其中包含一个具有各种字段的 JSON 正文,其中包括一个 File
类型的图像数组。
const body = {
title: 'title',price: 100,images: [...]
};
axios.post(url,body);
这不起作用,images
数组到达 Express 应用程序时为空。
我咨询了互联网并尝试使用 FormData
。但是,我看到的所有解决方案 (example) 中都只有图像,即
const images = [...];
const data = new FormData();
images.forEach(img => data.append(img.title,img));
但我想要整个东西——文本和图像,因为这个输入应该进入 MongoDB。
我曾尝试简单地将整个对象放在 FormData
中:
const data = new FormData();
data.append('body',body);
但我一定不明白 FormData
实际上是如何工作的,因为在 Express 中尝试 iterate over req.body
只会产生任何结果:
app.get((req,res) => {
const data = Object.fromEntries(req.body) // yields nothing
}
使用 multer
之类的任何其他尝试都会强化我做错了什么,因为我一生都无法获得非空的请求正文。
我想要做的是能够发送包含文本、数字和图像数组的完整 HTTP 数据主体,这样我就可以在 Express 应用程序上将这些图像保存到磁盘。 任何好的建议将不胜感激。
解决方法
您不能使用 json 发送图像(不是原始文件),但有一个带有表单数据的选项。 首先,你得把文件和普通数据分开,把普通数据解析成字符串。
const images = [...];
const body = new FormData();
// you have to put the images in the same field,and the server will recibe an array
images.forEach(img => body.append('images',img));
// the other data to send
const data = {
someData: true,moreData: 1,arrOfNormalData: [23,10];
}
const parsedData = JSON.stringify(data);
body.append('_jsonData',parsedData);
axios.post(url,body);
您正在请求的 _jsonData
字段中将 json 数据作为字符串发送。
然后在你的节点服务器上,你必须安装 multer 来配置它 ej
const path = require('path');
//this is for a ramdom id for file name
const { nanoid } = require('nanoid');
const multer = require('multer');
const storage = multer.diskStorage({
destination: function (req,file,cb) {
cb(null,'uploads')
},filename: function (req,nanoid() + path.extname(file.originalname));
}
})
const upload = multer({ storage: storage });
然后你可以创建一个中间件来解析数据(记住我们将它转换为字符串)到一个对象。
const parseJson = (field = '_jsonData') => {
return (req,res,next) => {
if (req.body[field] && typeof req.body[field] === 'string') {
req.body = JSON.parse(req.body[field]);
}
next();
};
};
然后让我们在路由中使用
app.get(upload.array('images',10),parseJson(),(req,res) => {
const data = req.body;// here the json data
const files = req.files;// here the uploaded files
}
我们添加了 upload.array('images',10)
,其中 images
是文件字段,10
是最大文件数
我们添加了 parseJons 中间件来解析搅拌到 json
希望它对你有帮助,不要使用 base64,如果你使用 base64,你可能会遇到问题。使用表单数据
附言。对不起,我英语说得不好。