Javascript Node.js base64 对下载的图像进行编码以用于数据 URI
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3709391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Node.js base64 encode a downloaded image for use in data URI
提问by betamax
Using Node v0.2.0 I am trying to fetch an image from a server, convert it into a base64 string and then embed it on the page in an image tag. I have the following code:
使用 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);
Note: This code requires "express" and "request". And of course, node. If you have npm installed, it should be as simple as "npm install express" or "npm install request".
注意:此代码需要“ express”和“ request”。当然,节点。如果你安装了 npm,它应该像“npm install express”或“npm install request”一样简单。
Unfortunately, this doesn't work as expected. If I do the conversion with the Google logo, then I get the following at the beginning of the string:
不幸的是,这不能按预期工作。如果我使用Google logo进行转换,那么我会在字符串的开头得到以下内容:
77+9UE5HDQoaCgAAAA1JSERSAAABEwAAAF8IAwAAAO+/ve+/ve+/vSkAAAMAUExURQBzCw5xGiNmK0t+U++/vQUf77+9BiHvv70WKO+/vQkk77+9D
77+9UE5HDQoaCgAAAA1JSERSAAABEwAAAF8IAwAAAO+/ve+/ve+/vSkAAAMAUExURQBzCw5xGiNmK0t+U++/vQUf77+9BiHvv70WKO+/vQkk77+9D
However if I use an online Base64 encoderwith the same image, then it works perfectly. The string starts like this:
但是,如果我使用具有相同图像的在线Base64 编码器,则它可以完美运行。字符串开始是这样的:
iVBORw0KGgoAAAANSUhEUgAAARMAAABfCAMAAAD8mtMpAAADAFBMVEUAcwsOcRojZitLflOWBR+aBiGQFiipCSS8DCm1Cya1FiyNKzexKTjDDSrLDS
iVBORw0KGgoAAAANSUhEUgAAARMAAABfCAMAAAD8mtMpAAADAFBMVEUAcwsOcRojZitLflOWBR+aBiGQFiipCSS8DCm1Cya1FiyNKzexKTjDDSrLDS
Where am I going wrong that this isn't working correctly? I have tried so many different js base64 implementations and they all don't work in the same way. The only thing I can think of is that I am trying to convert the wrong thing into base64, but what should I convert if that is the case?
我哪里出错了,这不能正常工作?我尝试了很多不同的 js base64 实现,但它们都以不同的方式工作。我唯一能想到的是我试图将错误的东西转换为 base64,但如果是这种情况,我应该转换什么?
采纳答案by bxjx
The problem is encoding and storing binary data in javascript strings. There's a pretty good section on this under Buffers at http://nodejs.org/api.html.
问题是在 javascript 字符串中编码和存储二进制数据。在http://nodejs.org/api.html 的Buffers 下有一个很好的部分。
Unfortunately, the easiest way to fix this involved changing the request npm. I had to add response.setEncoding('binary');on line 66 just below var buffer;in /path/to/lib/node/.npm/request/active/package/lib/main.js. This will work fine for this request but not others. You might want to hack it so that this is only set based on some other passed option.
不幸的是,解决这个问题的最简单方法是更改请求 npm。我不得不在/path/to/lib/node/.npm/request/active/package/lib/main.jsresponse.setEncoding('binary');下面的第66行添加var buffer;。这将适用于此请求,但不适用于其他请求。您可能想要修改它,以便仅根据其他一些传递的选项进行设置。
I then changed var buf = new Buffer(body)to var buf = new Buffer(body, 'binary');. After this, everything worked fine.
然后我改var buf = new Buffer(body)到var buf = new Buffer(body, 'binary');。在此之后,一切正常。
Another way to do this, if you really didn't want to touch the request npm, would be to pass in an object that implements Writable Stream in the responseBodyStream argument to request. This object would then store the streamed data from the response in it's own buffer. Maybe there is a library that does this already... i'm not sure.
另一种方法是,如果你真的不想接触请求 npm,将在 responseBodyStream 参数中传入一个实现 Writable Stream 的对象来请求。然后这个对象将来自响应的流数据存储在它自己的缓冲区中。也许有一个图书馆已经这样做了......我不确定。
I'm going to leave it here for now, but feel free to comment if you want me to clarify anything.
我暂时把它放在这里,但如果你想让我澄清任何事情,请随时发表评论。
EDIT
编辑
Check out comments. New solution at http://gist.github.com/583836
查看评论。http://gist.github.com/583836 上的新解决方案
回答by JFSIII
The following code (available at https://gist.github.com/804225)
以下代码(可在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;
});
});
should also produce a data URI without requiring any external modules.
还应该在不需要任何外部模块的情况下生成数据 URI。
回答by Steven Spungin
This works for me using request:
这适用于我使用请求:
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;
}
});
No need for any intermediate buffers. The key is to set encoding to null.
不需要任何中间缓冲区。关键是将编码设置为空。

