我在这里尝试在导出的Multer GridFS模块中动态更新metadata属性时有些挣扎。该模块包含一个“上传引擎”,用于处理将文件上传到我的数据库。这是multer-gridfs-storage库。

这是我的GridFs上传模块gridFs_upload_engine.js

> //Upload Engine const mongoose = require('mongoose'); const path =
> require('path'); const crypto = require('crypto'); const multer =
> require('multer'); const GridFsStorage =
> require('multer-gridfs-storage'); const Grid =
> require('gridfs-stream');
>
> //Init Upload Engine let gfs; const database = mongoose.connection;
> const mongoDb = process.env.MONGODB_URI || process.env.MLAB_URL;
>
> database.once('open', () => {   //Init Stream   gfs =
> Grid(database.db, mongoose.mongo);   gfs.collection('uploads'); });
>
> //Create Storage Engine const storage = new GridFsStorage({   url:
> mongoDb,   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: 'Add Metadata here'
>         };
>         resolve(fileInfo);
>       });
>     });   } });
>
> const uploadEngine = multer({ storage });
>
> module.exports = {   engine: uploadEngine,   gfs };


上面的metadata属性是我需要更改的。 fileinfo对象在上传时由GridFs添加到每个文件。我以为我可以在req参数中访问调用此中间件的路由的req.body,但它以undefined的形式返回。

这是我的测试路线:

const express = require('express');
const router = express.Router();

//Controllers
const upload_controller = require('../../controllers/uploader');

//Dependencies
const upload = require('../../utils/gridFs_upload_engine');

const { engine } = upload;
//Upload Single File
router.post(
  '/single',
  engine.single('file'),
  upload_controller.upload_single_file
);


这是我将GridFs中间件传递到我的API路由中的位置。这使控制器可以利用它。

这是我的upload controller

exports.upload_single_file = (req, res, next) => {
  console.log({ file: req.file });
  res.redirect('/');
};


console.log按预期注销用GridFs上传引擎上传的文件的信息。

我知道我需要以某种方式将参数传递给gridFs_upload_engine.js。由于此文件是导出的模块,因此我不确定如何完成此操作。我可以将此代码直接放入我的API控制器中并以这种方式进行处理,但是我希望它是一个可以从其他控制器调用的模块。

最佳答案

最后,我通过公开一个让我更新变量的函数解决了这个问题,然后将该变量用作metadata值。

API路线:

//Dependencies
const upload = require('../../utils/gridFs_upload_engine');

const { engine, updateMetadata } = upload;

//Upload Single File
router.post(
  '/single',
  (req, res, next) => {
    updateMetadata('xxxxxx'); //Static test value
    next();
  },
  engine.single('file'),
  upload_controller.upload_single_file
);


在这里,我添加了一个回调,其中包含上载引擎公开的updateMetadata()函数。在这里,我使用公开的metadata功能设置updateMetadata()。之后,通过使用next()router移至engine.single('file'),这实际上是处理文件上传的方式。

这是GridFs上传引擎:

//Create Storage Engine
let updatedMetadata;

const updateMetadata = id => {
  updatedMetadata = id;
};

const storage = new GridFsStorage({
  url: mongoDb,
  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: updatedMetadata ? updatedMetadata : null
        };
        resolve(fileInfo);
      });
    });
  }
});

const uploadEngine = multer({ storage });

module.exports = {
  engine: uploadEngine,
  updateMetadata,
  gfs
};


我不确定这是否是实现此目的的最佳方法,但是它可以正常运行并按预期运行,因此我将不再对此提出质疑。希望这对某人有帮助!

关于javascript - 通过request.body将元数据添加到GridFS文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55693758/

10-13 03:03