Forzar la codificación de texto plano en una solicitud de obtención de HTTPS en Node.
Problema
Relacionado con Obtener contenido HTML UTF-8 con http.get de Node – pero esa respuesta no está funcionando para mí.
Estoy tratando de llamar al endpoint de preguntas de la API de Stack Overflow:
none
https://api.stackexchange.com/2.3/questions?site=stackoverflow&filter=total
Lo cual debería devolver la siguiente respuesta JSON:
json
{"total":21951385}
Código de Ejemplo
Estoy usando el módulo de Node https
para enviar una solicitud get
de la siguiente manera:
const getRequest = (url: string) => new Promise((resolve, reject) => {
const options: RequestOptions = {
headers: {
'Accept': 'text/*',
'Accept-Encoding':'identity',
'Accept-Charset' : 'utf8',
}
}
<pre><code>const req = get(url, options, (res) => {
res.setEncoding('utf8');
let responseBody = '';
res.on('data', (chunk) => responseBody += chunk);
res.on('end', () => resolve(responseBody));
});
req.on('error', (err) => reject(err));
req.end();
</code></pre>
})
Y luego lo llamo de la siguiente manera:
ts
const questionsUrl = 'https://api.stackexchange.com/2.3/questions?&site=stackoverflow&filter=total'
const resp = await getRequest(questionsUrl)
console.log(resp)
Sin embargo, obtengo la respuesta:
none
▼�
�V*�/I�Q�22�454�0�♣��♥‼���↕
Lo que he intentado
He intentado varias variaciones de lo siguiente:
- Estoy llamando
setEncoding
autf8
en el flujo - He configurado el encabezado
Accept
atext/*
– lo cual> Proporciona un tipo MIME de texto, pero sin un subtipo
- He configurado el encabezado
Accept-Encoding
aidentity
– lo cual> Indica la función de identidad (es decir, sin modificación o compresión)
Este código también funciona perfectamente con prácticamente cualquier otro servidor API, por ejemplo, usando la siguiente URL:
none
https://jsonplaceholder.typicode.com/todos/1
Pero la API de StackOverflow funciona en cualquier otro lugar que haya intentado, por lo que debe haber una manera de instruir a Node cómo ejecutarla.
davy.ai
Solución
El problema con el código actual es que la respuesta de la API de Stack Overflow está comprimida con gzip, lo que significa que debe ser descomprimida antes de poder ser analizada como contenido UTF-8.
Para solucionar esto, necesitamos actualizar la función
getRequest
para manejar la compresión gzip configurando el encabezadoAccept-Encoding
engzip
y usando el módulozlib
para descomprimir la respuesta:La función
getRequest
actualizada verifica si la respuesta está comprimida con gzip mirando el encabezadocontent-encoding
de la respuesta. Si está comprimida con gzip, crea un flujo de transformaciónzlib.createGunzip()
para descomprimir la respuesta. Se llama asetEncoding('utf8')
en la respuesta descomprimida, y se concatena la respuesta en un búfer usando el eventodata
. El búfer se resuelve una vez que se dispara el eventoend
.Con estos cambios, la respuesta de la API debería ser descomprimida correctamente y devuelta como una cadena, que luego se puede analizar como JSON.