busboy-bodyparser 更改我的请求,以便 GridFsStorage 不会在 mongodb 中注册 request-data
busboy-bodyparser changes my request so that GridFsStorage doesn't register the request-data in mongodb
我是一名前端开发人员,试图拓宽我的视野,并制作将成为 MERN 应用程序的东西。我正在努力将图片上传到 mongodb.
首先我使用了 express bodyparser:
app.use(express.urlencoded({ extended: true }));
和 app.use(express.json());
像这样使用时,我成功地上传了文件,并且上传的文件显示在 MongoDB Compass 中。
我发现这不支持 multipart/form-data,所以我将 bodyparser 更改为 busboy-bodyparser 这样我就可以同时访问 form-data 和正在访问的文件上传。所以我将 bodyparser 更改为:
app.use(busboyBodyParser());
现在它不会将 request-data 上传到 mongodb。
我的上传控件是这样的:
const upload = require("../middleware/upload");
const uploadFile = async (req, res) => {
try {
req.file = req.files.file;
await upload(req, res);
if (req.file == undefined) {
return res.send(`You must select a file.`);
}
return res.send(`File has been uploaded.`);
} catch (error) {
console.log(error);
return res.send(`Error when trying upload image: ${error}`);
}
};
module.exports = {
uploadFile: uploadFile
};
我将 req.file 设置为 req.files.file 的原因是因为 busboy-bodyparser 从 req.files.file 而不是 [=65] 发送文件=],我认为此更改将使请求正常运行,但事实并非如此。
我的 upload-middleware 看起来像这样:
const promise = mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true });
const conn = mongoose.connection;
let gfs;
conn.once('open', () => {
gfs = Grid(conn, mongoose.mongo);
gfs.collection('uploads');
});
//create storage object
const storage = new GridFsStorage({
db: promise,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: 'uploads',
metadata: {
title: req.body.title,
orientation: req.body.orientation
}
};
resolve(fileInfo);
});
});
}
});
const uploadFile = multer({ storage }).single("file");
var uploadFilesMiddleware = util.promisify(uploadFile);
module.exports = uploadFilesMiddleware;
我相信这是记录 (node:15124) DeprecationWarning:侦听 Db class 上的事件的代码已被弃用,并将在下一个主要版本中删除。
(使用 node --trace-deprecation ...
显示创建警告的位置)
这是我不确定如何解决的另一个问题,但那是另一天的另一个问题。
我的最终目标是能够将文件连同附加的元数据(标题和方向)发送到 mongodb。
使用此代码,我能够从 upload-control 获取 “文件已上传” 消息,但在 mongoDB 罗盘中没有 file/chunks 已上传。使用 express-bodyparser 在 file-uploads(没有元数据)上上传效果很好,所以当我将其更改为 busboy-bodyparser 时,我按预期获得了文件和元数据,但未加载进入数据库,这让我相信新的 bodyparser 更改了请求,因此 GridFsStorage 不再识别它并且不会将数据放入数据库。但坦率地说,我只是在这里推测,而且我对后端的了解通常非常有限。
我在我认为的表格上使用了正确的 enctype:
<form
action="/upload"
method="POST"
enctype="multipart/form-data">
非常感谢任何提示或解释!
我是后端的完全初学者,所以不要害怕为我拼写 our :)
我成功修复了!
我不确定是什么原因造成的,但我相信 req.body 字段尚未填充或类似的东西。因此我关掉了
metadata: {
title: req.body.title,
orientation: req.body.orientation
}
使用:metadata: req.body
并且效果很好。
对于可能偶然发现此问题的任何其他后端新手,还请记住在 html 中命名您的输入,如下所示:<input name="title" type="text" />
它是与 [= 一起提交的名称属性26=]-form 并将密钥提供给 req.body,这样您就可以访问例如 req.body.title(在这里不起作用,但仍然值得了解)
我是一名前端开发人员,试图拓宽我的视野,并制作将成为 MERN 应用程序的东西。我正在努力将图片上传到 mongodb.
首先我使用了 express bodyparser:
app.use(express.urlencoded({ extended: true }));
和 app.use(express.json());
像这样使用时,我成功地上传了文件,并且上传的文件显示在 MongoDB Compass 中。
我发现这不支持 multipart/form-data,所以我将 bodyparser 更改为 busboy-bodyparser 这样我就可以同时访问 form-data 和正在访问的文件上传。所以我将 bodyparser 更改为:
app.use(busboyBodyParser());
现在它不会将 request-data 上传到 mongodb。
我的上传控件是这样的:
const upload = require("../middleware/upload");
const uploadFile = async (req, res) => {
try {
req.file = req.files.file;
await upload(req, res);
if (req.file == undefined) {
return res.send(`You must select a file.`);
}
return res.send(`File has been uploaded.`);
} catch (error) {
console.log(error);
return res.send(`Error when trying upload image: ${error}`);
}
};
module.exports = {
uploadFile: uploadFile
};
我将 req.file 设置为 req.files.file 的原因是因为 busboy-bodyparser 从 req.files.file 而不是 [=65] 发送文件=],我认为此更改将使请求正常运行,但事实并非如此。
我的 upload-middleware 看起来像这样:
const promise = mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true });
const conn = mongoose.connection;
let gfs;
conn.once('open', () => {
gfs = Grid(conn, mongoose.mongo);
gfs.collection('uploads');
});
//create storage object
const storage = new GridFsStorage({
db: promise,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: 'uploads',
metadata: {
title: req.body.title,
orientation: req.body.orientation
}
};
resolve(fileInfo);
});
});
}
});
const uploadFile = multer({ storage }).single("file");
var uploadFilesMiddleware = util.promisify(uploadFile);
module.exports = uploadFilesMiddleware;
我相信这是记录 (node:15124) DeprecationWarning:侦听 Db class 上的事件的代码已被弃用,并将在下一个主要版本中删除。
(使用 node --trace-deprecation ...
显示创建警告的位置)
这是我不确定如何解决的另一个问题,但那是另一天的另一个问题。
我的最终目标是能够将文件连同附加的元数据(标题和方向)发送到 mongodb。
使用此代码,我能够从 upload-control 获取 “文件已上传” 消息,但在 mongoDB 罗盘中没有 file/chunks 已上传。使用 express-bodyparser 在 file-uploads(没有元数据)上上传效果很好,所以当我将其更改为 busboy-bodyparser 时,我按预期获得了文件和元数据,但未加载进入数据库,这让我相信新的 bodyparser 更改了请求,因此 GridFsStorage 不再识别它并且不会将数据放入数据库。但坦率地说,我只是在这里推测,而且我对后端的了解通常非常有限。
我在我认为的表格上使用了正确的 enctype:
<form
action="/upload"
method="POST"
enctype="multipart/form-data">
非常感谢任何提示或解释! 我是后端的完全初学者,所以不要害怕为我拼写 our :)
我成功修复了!
我不确定是什么原因造成的,但我相信 req.body 字段尚未填充或类似的东西。因此我关掉了
metadata: {
title: req.body.title,
orientation: req.body.orientation
}
使用:metadata: req.body
并且效果很好。
对于可能偶然发现此问题的任何其他后端新手,还请记住在 html 中命名您的输入,如下所示:<input name="title" type="text" />
它是与 [= 一起提交的名称属性26=]-form 并将密钥提供给 req.body,这样您就可以访问例如 req.body.title(在这里不起作用,但仍然值得了解)