ExpressJS:req.body 值以字符串形式出现“[object Object]”
ExpressJS: req.body value comes as a string "[object Object]"
我正在尝试让 multer 在我的后端工作,以便能够处理文件。
我从 Angular 9+ 前端发送 (POST) 一个 FormData 对象到我的后端,看起来像:
foo: 'test',
bar: { id: 'someId', name: 'someName' },
file: { SOMEFILE }
在我的后端我有一个 server.js 文件:
const path = require('path');
const express = require("express");
const cors = require('cors');
const bodyParser = require("body-parser");
const mongoose = require('mongoose');
const app = express();
// SOME ROUTE IMPORTS -- Just the variable pointing to the route.
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB Connection Error:'));
// THERE I "USE" THE PREVIOUSLY IMPORTED ROUTES: app.use(routeX);
和有问题的路由文件(我们称之为 routeX):
const express = require('express');
const router = express.Router();
const multer = require('multer');
const MIME_TYPE_MAP = {
'image/png': 'png',
'image/jpeg': 'jpeg',
'image/jpg': 'jpg',
'application/pdf': 'pdf'
}
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const isValid = MIME_TYPE_MAP[file.mimetype];
let error = new Error("Invalid mimeType");
if (isValid) {
error = null;
}
cb(error, "docLibrary/equipment/");
},
filename: (req, file, cb) => {
const dateNow = Date.now();
const name = dateNow + '-' + file.originalname.toLowerCase().split(' ').join('_') + '-' + file.fieldname;
const ext = MIME_TYPE_MAP[file.mimetype];
cb(null,name + '.' + ext)
}
});
const upload = multer({storage: storage});
const cpUpload = upload.fields([{name: 'proforma', maxCount: 1}, {name: 'technicalDetails', maxCount: 1}]);
router.post('/newEquipment', cpUpload, async (req, res, next) => {
const url = req.protocol + '://' + req.get('host') + '/';
let receivedEquip = req.body;
console.log('receivedEquip\n');
console.log(JSON.stringify(receivedEquip));
console.log('\n');
}
问题是 console.log 函数为 req.body 提供了以下 JSON:
"foo": 'test',
"bar": "[object Object]",
"bar" 由于某种原因变成了一个 String 对象,它指定了它的值的类型......
我觉得这是因为 multer 以及我正在发送 FormData 的事实,但我不确定在这里看哪里......
有任何想法吗 ?
好的,试试这个;
router.post('/newEquipment', cpUpload, async (req, res, next) => {
const url = req.protocol + '://' + req.get('host') + '/';
let receivedEquip = JSON.parse(JSON.stringify(req.body));
let uploadFile = req.files.file // to get the file from the formData
console.log('receivedEquip\n');
console.log(receivedEquip);
console.log('\n');
});
好吧,毕竟它很愚蠢......
我不熟悉 FormData 对象,此时我希望有更好的方法将 blob 发送到后端。
不确定它是否存在,所以目前,解决方法是这样的:
问题的来源:
正如我们的好朋友 VSCode 所提到的 - FormData
不接受对象作为值。只有 Blobs
和 strings
:
Argument of type '{ test: string; secondTest: string; }' is not assignable to parameter of type 'string | Blob'.
Object literal may only specify known properties, and 'test' does not exist in type 'Blob'.ts(2345)
解决方案
因此,当附加到 FormData
时,您所要做的就是将 JSON Object
字符串化:
if (typeof currFormValue[key] === 'object') {
const currObject = JSON.stringify(currFormValue[key])
someFormDataObject.append(key, currObject);
}
并在服务器上将这些字段再次解析为 JSON
,如下所示:
Object.keys(req.body).map(reqKey => { if (reqKey === 'knowObject') { JSON.parse(req.body[reqKey]); } }
我确信有更好的结构可以使用,但我知道比询问 SO 使用哪种结构更清楚 ;)
谢谢大家!
我正在尝试让 multer 在我的后端工作,以便能够处理文件。 我从 Angular 9+ 前端发送 (POST) 一个 FormData 对象到我的后端,看起来像:
foo: 'test',
bar: { id: 'someId', name: 'someName' },
file: { SOMEFILE }
在我的后端我有一个 server.js 文件:
const path = require('path');
const express = require("express");
const cors = require('cors');
const bodyParser = require("body-parser");
const mongoose = require('mongoose');
const app = express();
// SOME ROUTE IMPORTS -- Just the variable pointing to the route.
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB Connection Error:'));
// THERE I "USE" THE PREVIOUSLY IMPORTED ROUTES: app.use(routeX);
和有问题的路由文件(我们称之为 routeX):
const express = require('express');
const router = express.Router();
const multer = require('multer');
const MIME_TYPE_MAP = {
'image/png': 'png',
'image/jpeg': 'jpeg',
'image/jpg': 'jpg',
'application/pdf': 'pdf'
}
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const isValid = MIME_TYPE_MAP[file.mimetype];
let error = new Error("Invalid mimeType");
if (isValid) {
error = null;
}
cb(error, "docLibrary/equipment/");
},
filename: (req, file, cb) => {
const dateNow = Date.now();
const name = dateNow + '-' + file.originalname.toLowerCase().split(' ').join('_') + '-' + file.fieldname;
const ext = MIME_TYPE_MAP[file.mimetype];
cb(null,name + '.' + ext)
}
});
const upload = multer({storage: storage});
const cpUpload = upload.fields([{name: 'proforma', maxCount: 1}, {name: 'technicalDetails', maxCount: 1}]);
router.post('/newEquipment', cpUpload, async (req, res, next) => {
const url = req.protocol + '://' + req.get('host') + '/';
let receivedEquip = req.body;
console.log('receivedEquip\n');
console.log(JSON.stringify(receivedEquip));
console.log('\n');
}
问题是 console.log 函数为 req.body 提供了以下 JSON:
"foo": 'test',
"bar": "[object Object]",
"bar" 由于某种原因变成了一个 String 对象,它指定了它的值的类型...... 我觉得这是因为 multer 以及我正在发送 FormData 的事实,但我不确定在这里看哪里...... 有任何想法吗 ?
好的,试试这个;
router.post('/newEquipment', cpUpload, async (req, res, next) => {
const url = req.protocol + '://' + req.get('host') + '/';
let receivedEquip = JSON.parse(JSON.stringify(req.body));
let uploadFile = req.files.file // to get the file from the formData
console.log('receivedEquip\n');
console.log(receivedEquip);
console.log('\n');
});
好吧,毕竟它很愚蠢...... 我不熟悉 FormData 对象,此时我希望有更好的方法将 blob 发送到后端。 不确定它是否存在,所以目前,解决方法是这样的:
问题的来源:
正如我们的好朋友 VSCode 所提到的 - FormData
不接受对象作为值。只有 Blobs
和 strings
:
Argument of type '{ test: string; secondTest: string; }' is not assignable to parameter of type 'string | Blob'.
Object literal may only specify known properties, and 'test' does not exist in type 'Blob'.ts(2345)
解决方案
因此,当附加到 FormData
时,您所要做的就是将 JSON Object
字符串化:
if (typeof currFormValue[key] === 'object') {
const currObject = JSON.stringify(currFormValue[key])
someFormDataObject.append(key, currObject);
}
并在服务器上将这些字段再次解析为 JSON
,如下所示:
Object.keys(req.body).map(reqKey => { if (reqKey === 'knowObject') { JSON.parse(req.body[reqKey]); } }
我确信有更好的结构可以使用,但我知道比询问 SO 使用哪种结构更清楚 ;)
谢谢大家!