使用Node + Jade + Express渲染存储在Mongo(GridFS)中的图像

8

我有一个使用GridFS存储在Mongo中的小型.png文件。我想使用Node + Express + Jade在我的Web浏览器中显示图像。我可以很好地检索图像,例如:

FileRepository.prototype.getFile = function(callback,id) {
this.gs = new GridStore(this.db,id, 'r');
this.gs.open(callback);
};

但我不知道如何使用Jade视图引擎进行渲染。文档中似乎没有任何信息。

有人可以指点我吗?

谢谢!

2个回答

16

我弄清楚了这个问题(感谢Timothy!)。问题在于我对所有这些技术以及它们如何相互配合的理解。对于任何其他想要使用Node、Express和Jade来显示来自MongoDB GridFS的图像的人...

我的MongoDB文档引用了存储在GridFS中的图像,其是作为字符串存储的ObjectId。例如,MyEntity {ImageId:'4f6d39ab519b481eb4a5cf52'} <-- 注意:ObjectId的字符串表示形式。我将其存储为字符串的原因是,将ObjectId存储时会在路由中产生疼痛,因为它呈二进制渲染,并且我无法弄清楚如何解决此问题(也许有人可以在这里帮忙?)。无论如何,我拥有的解决方案如下:

FileRepository - 从GridFS检索图像,我传递一个字符串Id,然后将其转换为BSON ObjectId(您还可以通过文件名获取文件):

FileRepository.prototype.getFile = function(callback,id) {
   var gs = new GridStore(this.db,new ObjectID(id), 'r');
   gs.open(function(err,gs){
      gs.read(callback);
   });
 };

Jade模板 - 渲染HTML标记:

img(src='/data/#{myentity.ImageId}')

App.JS文件 - 路由(使用Express)我设置了'/data/:imgtag'路由以获取动态图片:

app.get('/data/:imgtag', function(req, res) {
  fileRepository.getFile( function(error,data) {
     res.writeHead('200', {'Content-Type': 'image/png'});
     res.end(data,'binary');
  }, req.params.imgtag );
});

这样做就可以了。如果有任何问题,请告诉我 :)


8

我有点困惑你在这里尝试做什么,因为Jade是一种用于文本输出(如HTML)的压缩标记语言,而不是二进制内容。

由于您正在使用Jade,可能会像这样:

app.get/'images/:imgtag', function(req, res) {
    res.render('image', {imgtag: req.params.imgtag);
});

那么请尝试这个:
app.get/'images/:imgtag', function(req, res) {
    filerep.getFile( function(imgdata) {
        res.header({'Content_type': 'image/jpeg'})
        res.end(imgdata);
    }, req.params.imgtag );
});

这将以正确的mime类型将原始文件作为响应发送到HTTP请求。如果您想使用Jade提供模板(如图像弹出窗口),可以为弹出窗口使用不同的路由,甚至可以使用data:uri并在页面中编码图像数据。


修复MIME类型或从GridFS检测它。 - Timothy Meade
谢谢Timothy,你指引了我正确的方向。还有其他一些问题需要解决,为了完整起见,我在下面发布了我的解决方案。 - Click Ahead

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接