从二进制加载图像(Javascript - Ajax - MongoDB)

时间:2014-03-14 03:28:16

标签: javascript image mongodb binary

我在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,但图像不显示。 (我必须加入二进制数据,因为它们进入了一个数组)。 还有一些其他类似的帖子,但是他们没有我做过的任何事情(我认为)。

1 个答案:

答案 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编码数据,那么松散那个重要部分,并且每次都会发送数据。正如您所发现的那样,这也是一个非常混乱的过程。