Nodejs потребляют дефлятный ответ от внешнего API - PullRequest
0 голосов
/ 02 июля 2018

Это должен быть простой вопрос, но ради своей жизни я не могу заставить его работать, я использую веб-сервис, подобный этому:

var XMLHttpRequest = require('XMLHttpRequest').XMLHttpRequest;
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://rest.gestionix.com/api/v2/products? 
branch_id=7471&filter=0119080PMDSV&results_per_page=5&page=1&fields=id');
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.onreadystatechange = function(event) {
    if (xhr.readyState === 4) {
        if (xhr.status === 200) {
            console.log(xhr.responseText);
        }
    }
    console.log(xhr.getAllResponseHeaders());
};
xhr.setRequestHeader('Accept','application/json');
xhr.setRequestHeader('Accept-Encoding','decode');
xhr.setRequestHeader('Content-Encoding','decode');
xhr.setRequestHeader('Encoding','decode');
xhr.setRequestHeader('apikey', '---'); <<< of course I'm using an apikey
xhr.send();

API возвращает этот заголовок:

cache-control: max-age=60
content-length: 22766
content-type: application/json
content-encoding: deflate
server: Microsoft-IIS/10.0
x-aspnet-version: 4.0.30319
x-powered-by: ASP.NET
date: Mon, 02 Jul 2018 16:31:32 GMT
connection: close

Тем не менее, контент - это просто куча странных символов:

а ^ G4WkwCpȲG FZ} ϦBoWigu $ H ^; , Wf 촞 } : P e yE % 6 ٬ e1D ml 7UO DzK m } t " u dS7Q> 5у ֫ I ; E PH } / X & W { ) X SP v [ ݰ k W ׈ P { W > Z י R ׺4 Т] хт \ s ^ 5 q .t & Ǧ oP - ; ( 4 o6

Я пробовал с разными кодировками, но результат всегда один и тот же, я искал документацию о том, как распаковать это, но я не нашел ничего, что работает, если у кого-нибудь есть ссылка, которая может указать мне правильное направление, я буду очень признателен.

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Ну, я не хотел оставлять это без ответа на тот случай, если кому-то еще это понадобится. Сначала вам нужен этот код котельной плиты

/ ** Код котельной пластины * Обработка ответа. * @param {Object} headers * Хэш пар имя-значение заголовка ответа. * @param {String} body * Несжатый ответ тела. * / функция processResponse (заголовки, тело) {

  **do something with the response**

    } else {
        console.log("Response is empty.");
    }
}

/**
 * Manage an error response.
 *
 * @param {Error} error
 *   An error instance.
 */
function handleError(error) {
    // Error handling code goes here.
    console.log("Error Found: " + error);

}

/**
 * Obtain the encoding for the content given the headers.
 *
 * @param {Object} headers
 *   A hash of response header name-value pairs.
 * @return {String}
 *   The encoding if specified, or 'utf-8'.
 */
console.log('------------ Getting Charset  ------------');
function obtainCharset(headers) {
    // Find the charset, if specified.
    var charset;
    var contentType = headers['content-type'] || '';
    var matches = contentType.match(/charset=([^;,\r\n]+)/i);
    if (matches && matches[1]) {
        charset = matches[1];
    }
    console.log('------------ Charset is ' + charset + ' (utf-8 if null)  ------------');
    return charset || 'utf-8';
}

Эти функции позаботятся об обработке, они идут вверху.

И тогда вам нужно выполнить ваш запрос, в моем случае я использую обычный var request = require ('request-обещание');

var req = request ({ url: yoururlhere *, Заголовки: ** Ваши заголовки здесь }, функция wait (ошибка, ответ) { if (error) { return handleError (ошибка); } else if (response.statusCode> = 400) { return handleError (новая ошибка (util.format ( «Ответ с кодом состояния% s.», Response.statusCode ))); } console.log ('----------- Распаковка ответа -----------'); zlib.inflateRaw (Buffer.concat (buffers), function (gunzipError, bodyBuffer) { if (gunzipError) { return handleError (gunzipError); } var charset = receiveCharset (response.headers); processResponse (response.headers, bodyBuffer.toString (charset)); }); }); req.on ('data', function (buf) { buffers [buffers.length] = buf; });

0 голосов
/ 04 июля 2018

Сервер, вероятно, игнорирует ваш запрос к несжатым данным и отправляет вам сжатые данные. Он использует алгоритм дефляции, как указано в заголовке content-encoding. Вы можете спустить это самостоятельно. В nodejs есть собственная библиотека zlib, которая может дефлятировать данные.

var zlib = require("zlib")

// in response callback
zlib.deflate(xhr.response, function (error, result) {
    console.log(result.toString());
});

В моем случае мне не удалось прочитать данные XMLHttpRequest, поскольку эта библиотека не может обрабатывать двоичные данные и обрабатывает все данные в виде строк. Это проблема, потому что преобразование некоторых двоичных символов (например, 0) разбивает данные. Вместо этого я должен переключиться на библиотеку request . Код, который я использовал для проверки:

var zlib = require("zlib")
var request = require("request")

request('http://something...', { encoding: null }, function (error, response, body) {
    zlib.deflate(xhr.response, function (error, result) {
        console.log(result.toString());
    });
});
...