【问题标题】:Store an image in MongoDB using Node.js/Express and Mongoose使用 Node.js/Express 和 Mongoose 在 MongoDB 中存储图像
【发布时间】:2015-06-29 02:49:06
【问题描述】:

目前我使用 angular-file-upload 处理图像上传,我只是将图像保存到服务器的文件系统并在 HTML 中引用它。但是,我想尝试将图像直接存储在我为博客文章定义的架构内的数据库中。

var blogSchema = new Schema({
    title: String,
    author: String,
    body: String,
    likes: { type: Number, default: 0 },
    comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
    date: { type: Date, default: Date.now },
    imageURL: String   // instead of this

    image: // store it directly
});

"imageURL: String" stores the path to the image.

我想这样做,以便我可以拥有一个存储图像本身的字段。我在想我也许可以像我已经做的那样上传图像,而是在上传图像后转换图像并将其以二进制(或其他形式)存储在 Mongo 中。这可能吗?

谢谢!

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    下面的示例展示了如何使用 mongoose 将图像上传到 MongoDB。点击此链接查看original source

    var express = require('express');
    var fs = require('fs');
    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    
    var imgPath = '/path/yourimage.png';
    
    mongoose.connect('localhost', 'testing_storeImg');
    
    var schema = new Schema({
        img: { data: Buffer, contentType: String }
    });
    
    var A = mongoose.model('A', schema);
    
    mongoose.connection.on('open', function () {
      console.error('mongo is open');
    
      A.remove(function (err) {
        if (err) throw err;
    
        console.error('removed old docs');
    
        // store an img in binary in mongo
        var a = new A;
        a.img.data = fs.readFileSync(imgPath);
        a.img.contentType = 'image/png';
        a.save(function (err, a) {
          if (err) throw err;
    
          console.error('saved img to mongo');
    
          // start a demo server
          var server = express.createServer();
          server.get('/', function (req, res, next) {
            A.findById(a, function (err, doc) {
              if (err) return next(err);
              res.contentType(doc.img.contentType);
              res.send(doc.img.data);
            });
          });
    
          server.on('close', function () {
            console.error('dropping db');
            mongoose.connection.db.dropDatabase(function () {
              console.error('closing db connection');
              mongoose.connection.close();
            });
          });
    
          server.listen(3333, function (err) {
            var address = server.address();
            console.error('server listening on http://%s:%d', address.address, address.port);
            console.error('press CTRL+C to exit');
          });
    
          process.on('SIGINT', function () {
            server.close();
          });
        });
      });
    
    });
    

    【讨论】:

    • 感谢您的回答!我能够使用它将文件保存到数据库中。你知道我如何使用 Angular 在客户端加载图像吗?
    • @Jaco 从文件管理器中选择图像后如何自动获取图像的路径?
    • @BryanCho 您可以使用 fromCharCode 和 btoa 对从文档中获取的数据进行编码,然后将其分配给图像的源。例如。 src = "data:image/png;base64," + btoa(String.fromCharCode.apply(null, img.data))
    【解决方案2】:
    router.get("/:i", function (req, res) {
        
       var dataGet = {_id: req.params.i}
        
       fileModel.findOne(dataGet).exec(function (err, doc) {
    
            if (err) {
                return next(err)
            }
        
            var base64dataa = new Buffer(doc.fileData,'binary').toString('base64');
        
            var ress = {
               fileData: base64dataa,
               mime: doc.mimeType,
               name: doc.fileName
            }
    
           // res.json(ress)
           res.contentType('image/jpeg')
           res.send(doc.fileData)
       })
    })  
            
        
        
    router.post('/display/', function (req, res) {
    
           var data = {
               file: req.body.fileData,
               mime: req.body.mime,
               name: req.body.name
           }
        
           res.json(data)
    })
    

    【讨论】:

    • 您能解释一下避免删除的解决方案吗?
    【解决方案3】:

    这是将数据保存到 mongodb 的代码。 data 是二进制的。我可以显示这个 'image/jpg,base64,{{data}}' 但我不明白如何显示base64data

    file.on('data', function (data) {
                buffer += data;
    
                var file = new fileModel({
                    fileData: data
                })

    var Busboy = require('busboy');
    
    router.post('/upload', function (req, res) {
    
        var busboy = new Busboy({headers: req.headers});
        var base64data = "";
        var filetype = "";
        var name = "";
        var argum = [];
        var data2
    
        busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
    
            var buffer = "";
            filetype = mimetype;
            name = filename;
    
    
            // file.setEncoding('base64');
    
    
            file.on('data', function (data) {
                buffer += data;
    
                var file = new fileModel({
                    fileData: data
                })
                //
                file.save(function (err, file) {
                    if (err) {
                        return next(err)
                    }
                    // res.json(201, newData)
                    // console.log("Save in database" + file.desc)
                })
            });
            file.on('end', function () {
                base64data = buffer;
            });
        });
    
    
        busboy.on('field', function (fieldname, val, fieldnameTruncated, valTruncated) {
    
            argum.push(val);
        });
        busboy.on('finish', function () {
            var base64dataa = new Buffer(base64data, 'binary').toString('base64');
            res.json(base64dataa)
            var jsonBin = {
                base64data_: base64data, mime_: filetype, name_: name,
                owner_: argum[0], description_: argum[1]
            }
    
            // res.json(jsonBin)
    
            var file = new fileModel({
                fileData: jsonBin.base64data,
                mimeType: jsonBin.mime_,
                fileName: jsonBin.name_,
                fileOwner: jsonBin.owner_,
                desc: jsonBin.description_
            })
            //
            file.save(function (err, file) {
                if (err) {
                    return next(err)
                }
                // res.json(201, newData)
                console.log("Save in database" + file.desc)
            })
        });
    
        req.pipe(busboy);
    });

    【讨论】:

    • “我可以显示 'image/jpg,base64,{{data}}' 但我不明白如何显示 base64data”这句话我猜是缺少动词。如果我是正确的,请添加它。
    • 数据随二进制数据变化。我可以将其显示为 'image/jpg,base64,但 base64data 与数据不同。我什至无法显示它。
    猜你喜欢
    • 1970-01-01
    • 2011-12-29
    • 2011-05-29
    • 2015-09-23
    • 1970-01-01
    • 2011-07-06
    • 2020-06-28
    • 1970-01-01
    • 2011-12-07
    相关资源
    最近更新 更多