使用 Nodejs 检索存储在 Mongodb 中的图像
Retrieving Images stored in Mongodb with Nodejs
我将小缩略图存储在 MongoDB collection 中。虽然我可以用 .findOne()
提取它们,但我无法通过 ExpressJS 路由正确地返回它们。
我不会将拇指存储在磁盘上,因为 heroku 环境不能保证持久存储。我没有使用 GridFS,因为这些是小于 16MB 的拇指。
向 collection 中插入一个新文档是这样的:
MongoClient.connect(url, function(err, db){
var newImg = fs.readFileSync(req.file.path);
var encImg = newImg.toString('base64');
var newItem = {
description: req.body.description,
date: Date(),
contentType: req.file.mimetype,
size: req.file.size,
img: Buffer(encImg)
};
db.collection('myimages')
.insert(newItem, function(err, result){
if (err) { console.log(err); }
});
});
我可以像这样通过 Expressjs 路由为 img
提供服务:
router.get('/pictures/:picture', function(req, res){
/* my filename is actually a mdb oid */
var filename = req.params.picture;
MongoClient.connect(url, function(err, db){
db.collection('myimages')
.findOne({'_id': ObjectId(filename)}, function(err, results){
console.log(results); //<-- Output below
res.setHeader('content-type', results.contentType);
res.send(results.img);
});
});
});
nodejs console.log
returns 一个 object 这样的,
{ _id: 58f7ab923b7c842023cf80ec,
description: '',
date: 'Wed Apr 19 2017 13:25:22 GMT-0500 (CDT)',
contentType: 'image/jpeg',
size: 648436,
img:
Binary {
_bsontype: 'Binary',
sub_type: 0,
position: 864584,
buffer: <Buffer 2f 39 6a 2f 34 41 41 51 53 6b 5a 4a 52 67 41 42 41 51 41 41 53 41 42 49 41 41 44 2f 34 51 50 38 52 58 68 70 5a 67 41 41 54 55 30 41 4b 67 41 41 41 41 ... > }
}
但是浏览器控制台给我这样的错误:
Resource interpreted as Document but transferred with MIME type image/jpeg: "http://localhost:3000/picturewall/58f7ab923b7c842023cf80ec".
我是否错误地取消了编码?设置不正确 res
headers?
有人可以告诉我我做错了什么吗?
看来您在数据库中保存了 base64 图像。
你这样做img: Buffer(encImg)
。在node.js中默认的Buffer编码是utf8
,所以你的图像在MongoDB!
中以二进制类型的base64 utf8字符串保存在db中
正确的方法是在保存图像时指定缓冲区编码:
// ...
img: Buffer.from(encImg, 'base64')
// ...
这样当您以 res.send(results.img.buffer);
的形式向客户端发送响应时,您将发送二进制数据而不是 base64 字符串。
我将小缩略图存储在 MongoDB collection 中。虽然我可以用 .findOne()
提取它们,但我无法通过 ExpressJS 路由正确地返回它们。
我不会将拇指存储在磁盘上,因为 heroku 环境不能保证持久存储。我没有使用 GridFS,因为这些是小于 16MB 的拇指。
向 collection 中插入一个新文档是这样的:
MongoClient.connect(url, function(err, db){
var newImg = fs.readFileSync(req.file.path);
var encImg = newImg.toString('base64');
var newItem = {
description: req.body.description,
date: Date(),
contentType: req.file.mimetype,
size: req.file.size,
img: Buffer(encImg)
};
db.collection('myimages')
.insert(newItem, function(err, result){
if (err) { console.log(err); }
});
});
我可以像这样通过 Expressjs 路由为 img
提供服务:
router.get('/pictures/:picture', function(req, res){
/* my filename is actually a mdb oid */
var filename = req.params.picture;
MongoClient.connect(url, function(err, db){
db.collection('myimages')
.findOne({'_id': ObjectId(filename)}, function(err, results){
console.log(results); //<-- Output below
res.setHeader('content-type', results.contentType);
res.send(results.img);
});
});
});
nodejs console.log
returns 一个 object 这样的,
{ _id: 58f7ab923b7c842023cf80ec,
description: '',
date: 'Wed Apr 19 2017 13:25:22 GMT-0500 (CDT)',
contentType: 'image/jpeg',
size: 648436,
img:
Binary {
_bsontype: 'Binary',
sub_type: 0,
position: 864584,
buffer: <Buffer 2f 39 6a 2f 34 41 41 51 53 6b 5a 4a 52 67 41 42 41 51 41 41 53 41 42 49 41 41 44 2f 34 51 50 38 52 58 68 70 5a 67 41 41 54 55 30 41 4b 67 41 41 41 41 ... > }
}
但是浏览器控制台给我这样的错误:
Resource interpreted as Document but transferred with MIME type image/jpeg: "http://localhost:3000/picturewall/58f7ab923b7c842023cf80ec".
我是否错误地取消了编码?设置不正确 res
headers?
有人可以告诉我我做错了什么吗?
看来您在数据库中保存了 base64 图像。
你这样做img: Buffer(encImg)
。在node.js中默认的Buffer编码是utf8
,所以你的图像在MongoDB!
正确的方法是在保存图像时指定缓冲区编码:
// ...
img: Buffer.from(encImg, 'base64')
// ...
这样当您以 res.send(results.img.buffer);
的形式向客户端发送响应时,您将发送二进制数据而不是 base64 字符串。