2012-04-18 10 views
13

Encontré que el módulo de solicitud en js no puede manejar gzip o inflar la respuesta http de formato correctamente.Cómo usar la solicitud o el módulo http para leer la página de gzip en una cadena

por ejemplo:

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. 
} 

así que desea utilizar el código de ejemplo en documentos oficiales.

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

El problema es que el código está escribiendo la página web en un archivo, espero que pueda escribir la página en una cadena, de modo que pueda procesar la página. No pude encontrar ninguna clase como 'StringStream'.

Si alguien tiene alguna idea al respecto, será genial.

+0

Si createUnzip puede manejar tanto gzip e inflar, ¿por qué molestarse en escribir el código extra? ¿Es más lento? – CMCDragonkai

Respuesta

18

Transmita la respuesta al flujo gzip y úselo como lo haría con el objeto de respuesta original.

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

y esta es la respuesta correcta? en caso afirmativo, otorgue la respuesta correcta – abbood

+2

Use ese código para admitir ** desinflar ** también: 'if (res.headers ['content-encoding'] == 'deflate') {output = zlib.createInflate() ; res.pipe (salida); } ' –

+0

Tenga en cuenta que las claves del encabezado son minúsculas en la solicitud http de node.js; sin embargo, por especificación no distinguen entre mayúsculas y minúsculas. Entonces, cuando use otro módulo de solicitud, asegúrese de que los encabezados estén en minúscula o cambie el código ... – sebilasse

6

ejemplo simplificado:

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

Las respuestas de @Dawid y @Teemu veces freno de los caracteres de la respuesta en caso de codificación UTF-8. Este código funciona mucho mejor:

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

módulo de solicitud maneja las respuestas de gzip. Todo lo que tenemos que hacer es establecer el atributo 'gzip' en las opciones. Para una explicación detallada, visite el siguiente enlace. Ahí lo he explicado claramente con el ejemplo.

https://stackoverflow.com/a/38582506/5878471

Cuestiones relacionadas