【问题标题】:Nodejs consume deflate response from external APINodejs 使用来自外部 API 的 deflate 响应
【发布时间】:2018-12-10 23:07:48
【问题描述】:

这应该是一个简单的问题,但为了我的生活,我无法让它工作,我正在使用这样的网络服务:

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�촞�}�: �����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����������������������������������������������������q .t� ��������&�Ǧ��oP���- ��;( ��4����o6��

我尝试过使用不同的编码,但结果始终相同,我已经寻找有关如何解压缩的文档,但我没有找到任何有效的方法,如果有人有可以指向正确方向的链接我会很感激的。

【问题讨论】:

    标签: node.js api xmlhttprequest deflate


    【解决方案1】:

    服务器可能会忽略您对非未压缩数据的请求并将压缩数据发送给您。它使用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());
        });
    });
    

    【讨论】:

    • 谢谢,这确实有助于理解问题,但是它仍然无法正常工作,我添加了这个 zlib.deflate(xhr.result, function(error, result) { console.log("RESULT : " + result.toJSON); if (error) { console.log("ERROR if any: " + error); } });我得到了这个:结果:函数(){如果(this.length> 0){常量数据=新数组(this.length); for (var i = 0; i
    • 试试console.log("RESULT: " + result.toJSON()); (调用JSON添加括号)。我不知道你的 toJSON 方法是什么。通常我使用 JSON.stringify(result)。
    【解决方案2】:

    好吧,我不想让这个问题无人回答,以防万一其他人需要它。 首先你需要这个样板代码

    /** 样板代码 * 处理响应。 * @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 = 请求({ 网址:您的网址*, 标题:**yourheaderhere },函数等待(错误,响应){ 如果(错误){ 返回句柄错误(错误); } else if (response.statusCode >= 400) { 返回句柄错误(新错误(util.format( '状态码为 %s 的响应。', response.statusCode ))); } console.log('-----------解压响应-----------'); zlib.inflateRaw(Buffer.concat(buffers), function (gunzipError, bodyBuffer) { 如果(枪压缩错误){ 返回句柄错误(gunzipError); } var charset = gainCharset(response.headers); processResponse(response.headers, bodyBuffer.toString(charset)); }); }); req.on('数据', 函数 (buf) { 缓冲区[buffers.length] = buf; });

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-10
      • 1970-01-01
      • 2018-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-12
      • 1970-01-01
      相关资源
      最近更新 更多