Как использовать модуль запроса или http для чтения gzip-страницы в строку
Я обнаружил, что модуль запроса в js не может корректно обрабатывать gzip или раздувать HTTP-ответ формата.
например:
request({url:'some url'}, function (error, response, body) {
//if the content-encoding is gzip, the body param here contains binaries other than readable string. And even worse after you convert the body to buffer, u even can not gunzip it.
}
поэтому я хочу использовать пример кода в официальных документах.
var request = http.get({ host: 'izs.me',
path: '/',
port: 80,
headers: { 'accept-encoding': 'gzip,deflate' } });
request.on('response', function(response) {
var output = fs.createWriteStream('izs.me_index.html');
switch (response.headers['content-encoding']) {
// or, just use zlib.createUnzip() to handle both cases
case 'gzip':
response.pipe(zlib.createGunzip()).pipe(output);
break;
case 'deflate':
response.pipe(zlib.createInflate()).pipe(output);
break;
default:
response.pipe(output);
break;
}
});
Проблема в том, что код записывает веб-страницу в файл, я надеюсь, что он может написать страницу в строку, чтобы я мог обрабатывать страницу. Я не мог найти такой класс, как "StringStream".
Если у кого-нибудь есть идеи по этому поводу, это будет здорово.
Ответы
Ответ 1
Произведите ответ на поток gzip и используйте его, как вы бы использовали исходный объект ответа.
var req = http.request(options, function(res) {
var body = "";
res.on('error', function(err) {
next(err);
});
var output;
if( res.headers['content-encoding'] == 'gzip' ) {
var gzip = zlib.createGunzip();
res.pipe(gzip);
output = gzip;
} else {
output = res;
}
output.on('data', function (data) {
data = data.toString('utf-8');
body += data;
});
output.on('end', function() {
return next(false, body);
});
});
req.on('error', function(err) {
next(err);
})
Ответ 2
упрощенный пример:
var https = require('https');
var gunzip = require('zlib').createGunzip();
var options = {
host: 'api.stackexchange.com',
path: '/2.1/info?site=stackoverflow'
};
https.get(options, function(res) {
var body = '';
res.pipe(gunzip);
gunzip.on('data', function (data) {
body += data;
});
gunzip.on('end', function() {
console.log(JSON.parse(body));
});
});
Ответ 3
Я столкнулся с подобной проблемой и хотел продолжить использование библиотеки request
вместо встроенного http-модуля. Я обсуждал здесь два рабочих подхода: http://nickfishman.com/post/49533681471/nodejs-http-requests-with-gzip-deflate-compression. Один из них похож на ответ @Teemu, в то время как другой использует потоки.
Ответ 4
Модуль запроса обрабатывает ответы gzip. Все, что нам нужно сделать, это установить атрибут gzip в опциях. Подробное объяснение, пожалуйста, перейдите по ссылке ниже. Там я четко объяснил пример.
fooobar.com/questions/33134/...
Ответ 5
Ответы @Dawid и @Teemu иногда тормозят символы в ответе в случае кодировки utf-8. Этот код работает намного лучше:
function getGzipped(url, cb) {
// downloads gzipped file
http.get(url, function(res) {
let chunks = [];
res.on('data', function(chunk) {
chunks.push(chunk);
});
res.on('end', function() {
let buffer = Buffer.concat(chunks);
zlib.gunzip(buffer, function(err, decoded) {
if (err) throw err;
cb(decoded && decoded.toString());
});
});
});
}