2015-02-25 3 views
4

Я использую https.request() сделать запрос HTTPS с помощью следующей знакомой схеме:Node.js HTTP-запрос: как определить кодировку тела ответа?

var request = https.request(options, function (response) { 
    var chunks = []; 
    response.on('data', function (chunk) { 
     chunks.push(chunk); 
    }); 

    response.on('end', function() { 
     var buffer = Buffer.concat(chunks); 
     ... 
    }); 
}); 
... 
request.end(); 
... 

После того, как у меня есть готовый ответ Buffer, он должен быть упакован в объект JSON. Причина этого заключается в том, что я создаю туннель, в котором HTTP-ответ (его заголовки, статус и тело) должен быть отправлен как JSON через другой протокол.

Так что и текстовые и бинарные ответы могут быть поддержаны, что работает для меня до сих пор является кодирование Buffer в Base64 (используя buffer.toString('base64')) и unencode его на другом конце с помощью new Buffer(theJsonObject.body, 'base64'). Хотя это работает, было бы более эффективным, если бы я мог выборочно выполнять только кодировку Base64, если известно, что ответ HTTP-запроса имеет двоичный тип (например, изображения). В противном случае, в обратном вызове https.request(), показанном выше, я мог бы просто сделать chunk.toString() и передать тело ответа в объекте JSON как тип строки UTF-8. Мой объект JSON, вероятно, будет содержать дополнительное свойство, которое указывает на противоположный конец туннеля, является ли «тело» строкой UTF-8 (например, для .htm, .css и т. Д.) Или кодировкой Base64 (например, изображениями) ,

Что я могу сделать, это попытаться использовать тип MIME в ответе content-type, чтобы выяснить, будет ли ответ бинарным. Я бы, вероятно, поддерживал «белый список» типов, которые, как я знаю, можно с уверенностью предположить, это UTF-8 (например, «text/html» и т. Д.). Все остальные (включая, например, «image/png») будут кодироваться Base64.

Может ли кто-нибудь предложить лучшее решение?

+1

Я немного потерян. Почему вы не можете использовать заголовок Content-Type? И не беспокойтесь обо всем этом? – freakish

+0

Мне также интересно - не 'Content-Type' единственное возможное решение, чтобы узнать, есть ли его двоичный код или нет? – Charminbear

+0

Привет @freakish, проблема в том, что, поскольку я хочу упаковать содержимое ответа внутри объекта JSON наиболее эффективным с точки зрения размера образом, мне нужно программно определить, следует ли его рассматривать как двоичный. Если я просто всегда рассматривал его как строку (так что я сделал buffer.toString()) в обратном вызове данных), тогда двоичные данные изображения будут повреждены из-за кодирования. Я могу Base64-encode все (что моя демо передо мной прямо сейчас делает), но это бесполезно раздувает текстовые ответы (например, html, css, js). – Trevor

ответ

1

Можете ли вы использовать пакет file-type для определения типа файла путем проверки magic number буфера?

Установка

npm install --save file-type 

Использование

var fileType = require('file-type'); 
var safeTypes = ['image/gif']; 
var request = https.request(options, function (response) { 
    var chunks = []; 
    response.on('data', function (chunk) { 
     chunks.push(chunk); 
    }); 

    response.on('end', function() { 
     var buffer = Buffer.concat(chunks); 
     var file = fileType(buffer)); 
     console.log(file); 
     //=> { ext: 'gif', mime: 'image/gif' } 

     // mime isn't safe 
     if (safeTypes.indexOf(file.mime) == '-1') { 
      // do your Base64 thing 
     } 
    }); 
}); 
... 
request.end(); 
... 

Если вы хотите сохранить свой пакет коды бесплатно взглянуть на package source on Github, это довольно минимально.

+0

У меня был тот же самый вариант использования, что и спросил, и этот ответ работал идеально. Дал мне тип mime содержимого буфера! Отличный способ двойной проверки буфера - это фактически текст или тип, который вам сказал, что он находится в заголовке «content-type», иначе вы можете найти обработку двоичных данных в виде строки. Спасибо, Кевин Лири! – chwagssd

Смежные вопросы