简体   繁体   English

Node.js消耗来自外部API的deflate响应

[英]Nodejs consume deflate response from external API

This should be an easy question but for the sake of my life I cannot make it work, I'm consuming a web service like this: 这应该是一个简单的问题,但是为了我的生活,我无法使其正常运行,我正在使用这样的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();

The api returns this header: 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

However, the content is just a bunch of weird chars: 但是,内容只是一堆奇怪的字符:

a ^G4Wk wC p Ȳ G ?FZ} Ϧ Bo W i gu $H ^; a^G4Wk wC p Ȳ G FZ} Bo W i gu$H ^; ,Wf 촞 } : P e yE %6٬e1D ml 7UO DzK m }t " u 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 ,Wf 촞 } : %6,e1D ml 7UO DzK m } t。 dS7 Q >5 y I.;E PH } / X W{ XXSP v。[ k W׈ P { W >Z י R ׺4T ]X m< Ns'՟ f 0X:V.W C ҁ P #d T gb yIn c-+EP #= | V f 9 Ղ h .: r yF ر !σr L/E d7 7\\\\ +ɠ N 3 a {{- )。〜 \\s ^5 qq.t oP - ;( 4 o6

I have tried with different encodings but the result is always the same, I have look for documentation on how to decompress this but I have not find anything that works, if anyone have a link that can point me in the right direction I'll really appreciate it. 我尝试使用不同的编码,但是结果总是相同的,我一直在寻找有关如何解压缩的文档,但是我找不到任何有效的方法,如果有人有可以指向我正确方向的链接,我会真正欣赏它。

Server probably ignores your request to non uncompressed data and sends you compressed data. 服务器可能会忽略您对非压缩数据的请求,并向您发送压缩数据。 It uses deflate algorithm as said in content-encoding header. content-encoding标头中所述,它使用deflate算法。 You can deflate it yourself. 您可以自己放气。 nodejs has native library zlib which can deflate data. nodejs具有本机库zlib,可以压缩数据。

var zlib = require("zlib")

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

In my case I was unable to read data XMLHttpRequest because this library cannot process binary data and it process all data as strings. 就我而言,我无法读取XMLHttpRequest数据,因为该库无法处理二进制数据,而是将所有数据作为字符串处理。 This is problem because converting some binary characters (like 0) breaks the data. 这是有问题的,因为转换一些二进制字符(如0)会破坏数据。 I have to switched to request library instead. 我必须切换到请求库。 Code I was using to test is 我用来测试的代码是

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

Well, I didn't wanted to let this unanswered just in case someone else needs it. 好吧,我不想让这个问题无解,以防万一其他人需要它。 First you need this boiler plate code 首先,您需要此样板代码

/** Boiler Plate Code * Process the response. / **锅炉板代码*处理响应。 * @param {Object} headers * A hash of response header name-value pairs. * @param {Object}标头*响应标头名称-值对的哈希。 * @param {String} body * The uncompressed response body. * @param {String}主体*未压缩的响应主体。 */ function processResponse(headers, body) { * / function 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';
}

This functions will take care of the processing, they go at the top. 此功能将负责处理,它们位于顶部。

And then you need to run your request, in my case I am using a normal var request = require('request-promise'); 然后您需要运行您的请求,就我而言,我使用的是普通的var request = require('request-promise');

var req = request({ url: yoururlhere*, headers: **yourheadershere }, function wait(error, response) { if (error) { return handleError(error); } else if (response.statusCode >= 400) { return handleError(new Error(util.format( 'Response with status code %s.', response.statusCode ))); } console.log('----------- Decompressing response -----------'); zlib.inflateRaw(Buffer.concat(buffers), function (gunzipError, bodyBuffer) { if (gunzipError) { return handleError(gunzipError); } var charset = obtainCharset(response.headers); processResponse(response.headers, bodyBuffer.toString(charset)); }); }); var req = request({url: yoururlhere *,headers:** yourheadershere },function wait(error,response){if(error){return handleError(error);} else if(response.statusCode> = 400){返回handleError(new Error(util.format('Response with status code%s。',response.statusCode)));} console.log('-----------解压缩响应----- ------'); zlib.inflateRaw(Buffer.concat(buffers),function(gunzipError,bodyBuffer){if(gunzipError){return handleError(gunzipError);} var charset = getCharset(response.headers); processResponse (response.headers,bodyBuffer.toString(charset));});}); req.on('data', function (buf) { buffers[buffers.length] = buf; }); req.on('data',function(buf){buffers [buffers.length] = buf;});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM