如何从node.js服务器发送二进制数据的响应

3

我是mongodb的新手。

我使用以下代码片段存储二进制数据:

var data = fs.readFileSync(path);
  var image = new mongodb.Binary(data);
  //open connection/collection
var record = {picname: id, content: image   };
collection.save(record, {safe: true}, function(err,result){
  if(err)
  console.log(err.stack);
  });//save

我能在数据库中查看记录大小。其中包含二进制数据。记录大小与文件大小也匹配。我很高兴。
现在,从Mongo中检索相同的二进制数据并尝试将其发送作为响应:
var record = {picname: id};
  collection.findOne(record, function(err,result){
    if(err)
    console.log(err.stack);
    else
    {
    console.log('before read from db for download.');
    //HOW TO READ IMAGE/BINARY DATA FROM RESULT?
                                               //I need to send result in response. Any Idea?
    console.log('before read from db for download');
    }
    });

我正在使用以下代码片段发送二进制数据。但并非所有文件都能正常工作。可能是什么问题:

collection.findOne(record, function(err,result){
                if(err)
                    console.log(err.stack);
                else
                {
                    console.log('before read from db for download. result: [' + result.picname + " ], type: " + result.imagetype);
                    res.end(result.content.buffer, "binary");
                    console.log('Responded SUCCESS: ' + id );
                }
            });//findOne

请告诉我如何检索并通过响应发送。提前感谢。DD.

你说:“它不能处理所有文件。” 它能处理哪些文件,哪些文件不能处理?有没有规律?另外,它为什么不能工作?你是否收到错误提示,文件是否损坏等等? - Mike S
注意到 GIF 有时无法正常工作。 - user3297351
考虑使用GridFS,然后您就可以用以下方式编写:file.stream(true).pipe(res); - vedi
将图像存储在Mongodb中,而不是GridFS中。将二进制数据存储到Mongodb中。通过findOne从Mongodb获取二进制数据。对于小于4MB的图像,我应该使用GridFS吗?请建议。 - user3297351
如果你的文件大小不超过4Mb,那么它可以在没有GridFS的情况下工作。但是使用GridFS更加灵活。它将允许您在未来扩展而无需更改解决方案。 - vedi
谢谢。让我试试。但是,我读到GridFS适用于16MB以上的文件。是吗?GridFS需要特定的配置才能支持任何大小的文件吗?请建议。 - user3297351
1个回答

2
您的问题不在于存储和读取数据,而实际上是与内容类型有关。因此,理想情况下,您希望将此信息与数据一起存储,并在发送响应时返回正确的头信息。
其中一部分是MIME类型检测。有可用的模块,mmmagic是其中之一。
var Magic = require('mmmagic').Magic;

var magic = new Magic();

var data = fs.readFileSync(path);
var image = new mongodb.Binary(data);


//open connection/collection

magic.detect(data,function(err,result) {

    var record = {picname: id, content: image, mimeType: result };

    collection.save(record, {safe: true}, function(err,result){
        if(err)
            console.log(err.stack);
    });//save

});

编写标题的方法各不相同,但对于Node,您可以调用基本的“http”:

var record = {picname: id};
collection.findOne(record, function(err,result){
    if(err)
        console.log(err.stack);
    else {
        res.writeHead(200, {
            'Content-Type': result.mimeType,
            'Content-Length': result.content.length
        });
        res.write(result.content.buffer);
        res.end();
    }
});

因此,这里返回的有效数据是由其正确的MIME类型标识的二进制数据。因此,您可以从提供查找文档并直接在浏览器中查看的URL访问它,就像服务于常规图像文件一样。


应用程序在 content.length 处崩溃。因此,只添加了 result.mimetype。对于某些文件,它可以正常工作,但不是所有文件。 - user3297351
1
对于那些想知道为什么程序崩溃的人来说,应该是result.content.buffer.length - Matt Pope

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