我在MongoDB上保存了一张图片。该模型如下:
picture: {
metadata: {
name: { type: String, default: null },
comment: { type: String, default: null },
publisherID: { type: String,default: null },
date: { type: Date, default: Date.now },
size: { type: Number,default: 0 },
type: { type: String, default: null }
},
data: { type: Buffer, default: null },
tags: Array
}
现在我需要再次从数据库加载图像。
我进行了一次AJAX调用并请求带有id的图片。
$.ajax({
type: "POST",
url: window.location.origin + '/picture',
contentType: 'application/json',
dataType: 'json',
async: true,
data: JSON.stringify({ id: id }),
success: function (result) {
console.log(result);
a = result;
var img = result.result[0].picture.data.join("").toString('base64');
img = "data:" + result.result[0].picture.metadata.type + ";base64," + img;
$('#img').attr('src', img);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('error ' + textStatus + " " + errorThrown);
success = false;
}
});
这是服务器上的处理程序
var Picture = require('../models/picture');
Picture.find({ "_id": req.body.id}, function (err, pic) {
if (err || !pic)
res.end(JSON.stringify({ result: "error" }));
if (pic) {
console.log(pic);
res.end(JSON.stringify({ result: pic }));
}
})
我已将二进制数据转换为base64,但图像不显示。 (我必须加入二进制数据,因为它们进入了一个数组)。 还有一些其他类似的帖子,但是他们没有我做过的任何事情(我认为)。
答案 0 :(得分:1)
正如评论中所述,在您的应用程序中有一个单独的端点,使这些调用“看起来像”标准的静态文件请求是更好。所以我首先要做的是稍微改变你的架构:
picture: {
metadata: {
name: { type: String, default: null },
comment: { type: String, default: null },
publisherID: { type: String,default: null },
date: { type: Date, default: Date.now },
size: { type: Number,default: 0 },
type: { type: String, default: null }
},
path: { type: String, required: true },
mime: { type: String, required: true },
data: { type: Buffer, default: null },
tags: Array
}
因此,添加两个字段来识别要匹配的图像的“路径”,并添加“mime”作为文件的mime类型。因此,“path”是一个比_id
更“友好”的标识符,并且“mime-type”将在insert中设置以匹配返回的内容类型。
然后设置一条路线来提供内容:
app.get('/images/:imgname', function(req,res) {
Picture.find({ "picture.path": req.param("imgname") }, function(err,pic) {
if (err) // checking here
// Sending response
res.set('Content-Type', pic.mime);
res.send( pic[0].picture.data );
});
})
所以,当你提出类似的请求时:
wget http://localhost:3000/images/test.png
会发生这种情况:
找到“test.png”的文件“path”
将“picture.mime”的文档属性指定为响应的内容类型
将二进制数据作为回复发送回来
因此对于客户端来说,它是一个实际的文件作为响应,关键是“浏览器”可以缓存这个和没有点击你的应用程序“缓存“复制有效。
如果您在JSON响应中嵌入Base64编码数据,那么松散那个重要部分,并且每次都会发送数据。正如您所发现的那样,这也是一个非常混乱的过程。