我试图让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上问哪个结构更好;)
谢谢大家!