Node.js使用来自外部API的deflate响应

时间:2018-07-02 17:19:58

标签: node.js api xmlhttprequest deflate

这应该是一个简单的问题,但是为了我的生活,我无法使其正常运行,我正在使用这样的Web服务:

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

但是,内容只是一堆奇怪的字符:

a。^G4Wk.wC.����p.G.FZ} .Bo.W.i.gu $ H. ^; ,Wf�촞�}�:�����������������%6,e1D�ml�7UO�DzK����m��} t。 ��dS7�Q��>5�y֫� I.; E.PH。}��/��X���&��W{�)X�SP��v�[�ݰ��k�W׈����P {�W �>Z���י�R��׺4T�]X�m<�Ns'՟��������f�0X:V�W�C��ҁ��P。 #d���T�gb�yI n��c-�+EP�#= |�V���f�9�Ղ�h ::����r����yF�ر����Se�!σr�L/ E���d7�7�\\ +ɠ�N��3� a。{��-�)�〜���。��\\ s ^ 5.q.t。                               ��������&�ǦoP���-��-;( ��4���o6��

我尝试使用不同的编码,但结果始终是相同的,我一直在寻找有关如何解压缩该文件的文档,但如果有任何链接可以将我指向正确的方向,则我找不到任何有效的文件我会很感激的。

2 个答案:

答案 0 :(得分:0)

服务器可能会忽略您对非压缩数据的请求,并向您发送压缩数据。它使用content-encoding标头中所述的deflate算法。您可以自己放气。 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());
    });
});

答案 1 :(得分:0)

好吧,我不想让这个问题没有答案,以防万一有人需要它。 首先,您需要此样板代码

/ **锅炉板代码      *处理响应。      * @param {Object}标头      *响应标头名称/值对的哈希。      * @param {String}正文      *未压缩的响应主体。      * /     函数processResponse(headers,body){

  **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-promise');

var req = request({         网址:您的网址*,         标头:**您的标头此处     },函数wait(错误,响应){         如果(错误){             返回handleError(错误);         }否则,如果(response.statusCode> = 400){             返回handleError(new Error(util.format(                 “使用状态代码%s。响应”,response.statusCode             )));         }         console.log('-----------解压缩-----------');         zlib.inflateRaw(Buffer.concat(buffers),function(gunzipError,bodyBuffer){             如果(gunzipError){                 返回handleError(gunzipError);             }             var charset = getCharset(response.headers);             processResponse(response.headers,bodyBuffer.toString(charset));         });     });     req.on('data',function(buf){         buffers [buffers.length] = buf;     });