Node.js base64 кодирует загруженный образ для использования в URI данных - PullRequest
15 голосов
/ 14 сентября 2010

Использование 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 ". И конечно, узел . Если у вас установлен npm, он должен быть таким же простым, как «npm install express» или «npm install request».

К сожалению, это не работает, как ожидалось. Если я сделаю преобразование с логотипом Google , то в начале строки получу следующее:

77 + 9UE5HDQoaCgAAAA1JSERSAAABEwAAAF8IAwAAAO + / ве + / ве + / vSkAAAMAUExURQBzCw5xGiNmK0t + U ++ / vQUf77 + 9BiHvv70WKO + / vQkk77 + 9D

Однако, если я использую онлайн Base64 кодировщик с тем же изображением, то он работает отлично. Строка начинается так:

iVBORw0KGgoAAAANSUhEUgAAARMAAABfCAMAAAD8mtMpAAADAFBMVEUAcwsOcRojZitLflOWBR + aBiGQFiipCSS8DCm1Cya1FiyNKzexKTjDDSrLDS

Где я ошибаюсь, что это работает неправильно? Я пробовал так много разных реализаций js base64, и все они не работают одинаково. Единственное, о чем я могу думать, это то, что я пытаюсь преобразовать неправильную вещь в base64, но что я должен преобразовать, если это так?

Ответы [ 3 ]

13 голосов
/ 15 сентября 2010

Проблема заключается в кодировании и хранении двоичных данных в строках JavaScript. В разделе Buffers есть довольно хороший раздел на http://nodejs.org/api.html.

К сожалению, самый простой способ исправить это - изменить запрос npm. Мне пришлось добавить response.setEncoding('binary'); в строке 66 чуть ниже var buffer; в /path/to/lib/node/.npm/request/active/package/lib/main.js. Это будет хорошо работать для этого запроса, но не для других. Возможно, вы захотите взломать его, чтобы он устанавливался только на основе другого переданного параметра.

Затем я изменил var buf = new Buffer(body) на var buf = new Buffer(body, 'binary');. После этого все работало нормально.

Другой способ сделать это, если вы действительно не хотите касаться запроса npm, - передать объект, реализующий Writable Stream, в аргумент responseBodyStream для запроса. Затем этот объект будет хранить потоковые данные из ответа в своем собственном буфере. Может быть, есть библиотека, которая делает это уже ... я не уверен.

Я пока оставлю это здесь, но не стесняйтесь комментировать, если вы хотите, чтобы я что-то прояснил.

EDIT

Ознакомьтесь с комментариями. Новое решение на http://gist.github.com/583836

8 голосов
/ 01 февраля 2011

Следующий код (доступен на 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 данных без каких-либо внешних модулей.

1 голос
/ 19 февраля 2017

Это работает для меня, используя запрос:

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;
    }
});

Нет необходимости в каких-либо промежуточных буферах.Ключ должен установить кодировку на ноль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...