首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过request.body向GridFS文件添加元数据

通过request.body向GridFS文件添加元数据
EN

Stack Overflow用户
提问于 2019-04-16 00:41:35
回答 2查看 1.5K关注 0票数 2

我在尝试动态更新导出的Multer GridFS模块中的metadata属性时遇到了一些困难。这个模块包含一个‘上传引擎’,处理上传文件到我的数据库。这是multer-gridfs-storage库。

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

代码语言:javascript
复制
> //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

下面是我的测试路线:

代码语言:javascript
复制
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

代码语言:javascript
复制
exports.upload_single_file = (req, res, next) => {
  console.log({ file: req.file });
  res.redirect('/');
};

console.log会如期注销使用GridFs上传引擎上传的文件的信息。

我知道我需要以某种方式将一个参数传递给gridFs_upload_engine.js。因为这个文件是一个导出的模块,所以我不完全确定如何实现这一点。我可以将这段代码直接放到我的API控制器中,然后这样做,但我希望它是一个可以从其他控制器调用的模块。

EN

回答 2

Stack Overflow用户

发布于 2019-04-16 03:00:23

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

API路由:

代码语言:javascript
复制
//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()函数。在这里,我使用公开的updateMetadata()函数设置metadata。然后,通过使用next()router转移到engine.single('file')上,它实际上处理文件的上传。

这是GridFs上传引擎:

代码语言:javascript
复制
//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
};

我不确定这是否是最好的方法,但它工作正常,正如预期的那样,所以我不会进一步质疑它。希望这对某些人有帮助!

票数 2
EN

Stack Overflow用户

发布于 2020-09-22 05:19:22

上面的解决方案不起作用,在谷歌上搜索了一大堆后,我找到了这个cant access req.body inside metadata. · Issue #1 · devconcept/multer-gridfs-storage

我觉得很傻,因为在创建存储引擎时,您可以访问请求之前,我还没有看到它

代码语言:javascript
复制
const storage = new GridFsStorage({
url: db,
options: { useNewUrlParser: true, useUnifiedTopology: true },
file: (req, file) => {
    return new Promise((resolve, reject) => {
        crypto.randomBytes(16, (err, buf) => {
            if (err) {
                return reject(err);
            }
            let metaData;
            if(req.body && req.body.checked){
              metaData = true
            }
            const filename = buf.toString("hex") + path.extname(file.originalname);
            const fileInfo = {
                filename: filename,
                bucketName: "uploads",
                metadata: metaData ? metaData : null
                
            };
            resolve(fileInfo);
        });
    });
}

});

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55693758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档