首页 文章

从Mongo的Gridfs流式传输的图像未在浏览器中显示

提问于
浏览
0

我在这里发布这个问题,我一直在阅读很多相关的帖子,但是他们中的任何一个都帮我完成了它的工作 .

这个想法非常简单:我有一个基于MEAN的应用程序,可以将图像上传到GridFS - 无需将其本地存储到服务器 - 然后在浏览器中将其可视化 .

让我们开始吧 . 我正在使用 angular-file-upload 模块从AngularJS上传图像 . 因此,在我的一个AngularJS控制器中,我有:

$scope.onFileSelect = function(file) {

   var fileName = file.name;

   $scope.upload = $upload.upload({
       url: '/file/uploadFile', //this is the node route for uploading the file
       headers: {
            'fileName':fileName
       },
       file: file
   }).
   success(function(data, status, headers, config) {
    //DOING STUFF
   }.
   error(function(data, status, headers, config) {
    //DOING OTHER STUFF
   });
}

在我的Node Express服务器中,我正在处理上传请求和通过 grids-stream 模块下载图像的请求 . 这允许我直接在GridFS中流式传输和保存图像,而无需临时将其保存在服务器中 .

var mongoose = require('mongoose'),Grid = require('gridfs-stream'),gfs;

mongoose.connection.once('open',function() {
    gfs = Grid(mongoose.connection.db, mongoose.mongo);
});

exports.uploadFile = function(req, res) {
   var fileNameHeader = req.headers['filename'];
   //creating a unique filename
   var name = uuid.v1();
   var extIndex = fileNameHeader.lastIndexOf('.');
   var extension = fileNameHeader.substr(extIndex);
   var fileName = name+extension;

   var writeStream  = gfs.createWriteStream({
       filename: fileName,
       root: 'imagesGrid'
   });
   req.pipe(writeStream);
   writeStream.on('close',function() {
      //DOING STUFF 
   });
}

exports.downloadFile = function(req,res) {  
   var name = req.params.name;
   var readStream = gfs.createReadStream({
      filename: name,
      root: 'imagesGrid'
   });
   res.header({'Content-type': mime.lookup(name)});
   readStream.pipe(res);
};

在客户端,我有这个HTML指令生成所有HTML图像元素:

<my-image-draggable ng-repeat="image in userImages">
</my-image-draggable>

my-image-draggable 所在的地方,作为其中一个要素:

<img ng-src='{{image.imageId.location}}'>

在运行时, {{image.imageId.location}} 被转换为(例如): '/file/getFile/2350bcf0-53b4-11e4-9f6b-9fc9a66908c4.jpg' ,因此原则上

<img ng-src='/file/getFile/2350bcf0-53b4-11e4-9f6b-9fc9a66908c4.jpg'>

应该向服务器中的 downloadFile 发出HTTP GET请求,该图像应该从GridFS流式传输,最后显示在浏览器中 . 问题是图像不显示 .

我还尝试在Angular控制器中预处理服务器发送的图像数据,以便将其编码为base64,并在运行时让 ng-src 类似于:

'data:image/jpeg;base64,'+Base64.encode(data);

但它也不起作用 .

我也尝试手动调用 downloadFile 路由,但没有结果 . 我无法弄清楚为什么这不起作用 . 我想知道图像是否正确保存到GridFS .

有什么建议吗?遇到同样问题的其他人?

非常感谢!

1 回答

  • 0

    好像你使用socket.io已经解决了你的问题,但我只是为自己解决了一些问题并认为我会分享 .

    对于我的情况,我需要能够存储有关图像的信息,如图像 Headers . 我决定坚持使用标准的html帖子表格,其中包含用户提供的所有输入字段以及文件本身 . 我使用Multer作为上传路由的中间件,所以当请求到达我的 uploadImg 路由时,Multer已经为表单字段和文件解析了它 .

    Multer将文件存储为临时文件(尚未找到将其流式传输到 gridfs-stream 同时仍解析表单字段的方法) . 一个快速的解决方案是流式传输保存的临时文件,然后当它对我们的情况足够好时删除它 .

    var uploadImg = function(req,res) {
          var writestream = gfs.createWriteStream({
            filename: req.files.file.name,
            mode:'w',
            content_type:req.files.file.mimetype,
            metadata:req.body,
          });
        fs.createReadStream(req.files.file.path).pipe(writestream);
    
        writestream.on('close', function (file) {
            res.send("Success!");
            fs.unlink(req.files.file.path, function (err) {
              if (err) console.error("Error: " + err);
              console.log('successfully deleted : '+ req.files.file.path );
            });
        });
    
    };
    

    另见:MongoError when uploading a file using mongoose, gridfs-stream and multer

相关问题