Node.js base64编码下载的图像以用于数据URI

时间:2010-09-14 13:40:08

标签: javascript image node.js base64

使用Node v0.2.0我试图从服务器获取图像,将其转换为base64字符串,然后将其嵌入到图像标记的页面上。我有以下代码:

var express = require('express'),
request = require('request'),
sys = require('sys');

var app = express.createServer(
    express.logger(),
    express.bodyDecoder()
);

app.get('/', function(req, res){

    if(req.param("url")) {
        var url = unescape(req.param("url"));
        request({uri:url}, function (error, response, body) {
          if (!error && response.statusCode == 200) {

                var data_uri_prefix = "data:" + response.headers["content-type"] + ";base64,";
                var buf = new Buffer(body);
                var image = buf.toString('base64');

                image = data_uri_prefix + image;

                res.send('<img src="'+image+'"/>');

          }
        });
    }
});

app.listen(3000);

注意:此代码需要“express”和“request”。当然,node。如果您安装了npm,它应该像“npm install express”或“npm install request”一样简单。

不幸的是,这不能按预期工作。如果我使用Google logo进行转换,那么我会在字符串的开头获得以下内容:

  

77 + 9UE5HDQoaCgAAAA1JSERSAAABEwAAAF8IAwAAAO + / VE + / VE + / vSkAAAMAUExURQBzCw5xGiNmK0t + U + + / + vQUf77 + 9BiHvv70WKO / vQkk77 + 9D

但是,如果我使用具有相同图像的在线Base64 encoder,那么它的效果非常好。字符串的开头如下:

  

iVBORw0KGgoAAAANSUhEUgAAARMAAABfCAMAAAD8mtMpAAADAFBMVEUAcwsOcRojZitLflOWBR + aBiGQFiipCSS8DCm1Cya1FiyNKzexKTjDDSrLDS

我哪里错了,这不能正常工作?我已经尝试了很多不同的js base64实现,但它们都不能以相同的方式工作。我唯一能想到的是我试图将错误的东西转换成base64,但是如果是这样的话我应该转换什么呢?

3 个答案:

答案 0 :(得分:13)

问题是在javascript字符串中编码和存储二进制数据。在http://nodejs.org/api.html的Buffers下有一个相当不错的部分。

不幸的是,解决此问题的最简单方法是更改​​请求npm。我必须在/path/to/lib/node/.npm/request/active/package/lib/main.js中response.setEncoding('binary');下方的第66行添加var buffer;。这适用于此请求但不适用于其他请求。您可能想要破解它,以便仅基于其他一些传递选项进行设置。

然后我将var buf = new Buffer(body)更改为var buf = new Buffer(body, 'binary');。在此之后,一切正常。

另一种方法是,如果你真的不想触摸请求npm,那就是在requestBodyStream参数中传入一个实现Writable Stream的对象来请求。然后,该对象将响应中的流数据存储在自己的缓冲区中。也许有一个库已经做到了......我不确定。

我现在要把它留在这里,但如果你想让我澄清任何事情,请随时发表评论。

修改

查看评论。 http://gist.github.com/583836

的新解决方案

答案 1 :(得分:8)

以下代码(https://gist.github.com/804225提供)

var URL = require('url'),
    sURL = 'http://nodejs.org/logo.png',
    oURL = URL.parse(sURL),
    http = require('http'),
    client = http.createClient(80, oURL.hostname),
    request = client.request('GET', oURL.pathname, {'host': oURL.hostname})
;

request.end();
request.on('response', function (response)
{
    var type = response.headers["content-type"],
        prefix = "data:" + type + ";base64,",
        body = "";

    response.setEncoding('binary');
    response.on('end', function () {
        var base64 = new Buffer(body, 'binary').toString('base64'),
            data = prefix + base64;
        console.log(data);
    });
    response.on('data', function (chunk) {
        if (response.statusCode == 200) body += chunk;
    });
});

还应生成数据URI,而无需任何外部模块。

答案 2 :(得分:1)

这适用于我使用请求:

const url = 'http://host/image.png';
request.get({url : url, encoding: null}, (err, res, body) => {
    if (!err) {
        const type = res.headers["content-type"];
        const prefix = "data:" + type + ";base64,";
        const base64 = body.toString('base64');
        const dataUri = prefix + base64;
    }
});

无需任何中间缓冲区。关键是将编码设置为null。