Nodejs 消耗来自外部 API 的压缩响应
Nodejs consume deflate response from external API
这应该是一个简单的问题,但为了我的生活,我无法让它工作,我正在使用这样的网络服务:
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();
本apireturns本header:
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��"���� �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��
我尝试过不同的编码,但结果总是一样的,我一直在寻找有关如何解压缩它的文档,但我没有找到任何有效的方法,如果有人有 link 可以指出我在正确的方向我真的很感激。
服务器可能会忽略您对非未压缩数据的请求并向您发送压缩数据。它使用 content-encoding
header 中所述的放气算法。你可以自己放气。 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());
});
});
好吧,我不想为了以防其他人需要它而让这个无人回答。
首先你需要这个样板代码
/** 锅炉板代码
* 处理响应。
* @param {Object} headers
* 响应 header name-value 对的散列。
* @param {字符串} body
* 未压缩的响应 body。
*/
函数 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 = 请求({
url:你的url在这里*,
headers:**你的header这里
},函数等待(错误,响应){
如果(错误){
return handleError(错误);
}否则如果(response.statusCode>=400){
return handleError(新错误(util.format(
'Response with status code %s.'、response.statusCode
)));
}
console.log('------------解压响应------------');
zlib.inflateRaw(Buffer.concat(缓冲区), 函数 (gunzipError, body缓冲区) {
如果(gunzipError){
return handleError(gunzipError);
}
var charset = obtainCharset(response.headers);
processResponse(response.headers, bodyBuffer.toString(字符集));
});
});
req.on('data', 函数 (buf) {
缓冲区[buffers.length] = buf;
});
这应该是一个简单的问题,但为了我的生活,我无法让它工作,我正在使用这样的网络服务:
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();
本apireturns本header:
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��"���� �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��
我尝试过不同的编码,但结果总是一样的,我一直在寻找有关如何解压缩它的文档,但我没有找到任何有效的方法,如果有人有 link 可以指出我在正确的方向我真的很感激。
服务器可能会忽略您对非未压缩数据的请求并向您发送压缩数据。它使用 content-encoding
header 中所述的放气算法。你可以自己放气。 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());
});
});
好吧,我不想为了以防其他人需要它而让这个无人回答。 首先你需要这个样板代码
/** 锅炉板代码 * 处理响应。 * @param {Object} headers * 响应 header name-value 对的散列。 * @param {字符串} body * 未压缩的响应 body。 */ 函数 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 = 请求({ url:你的url在这里*, headers:**你的header这里 },函数等待(错误,响应){ 如果(错误){ return handleError(错误); }否则如果(response.statusCode>=400){ return handleError(新错误(util.format( 'Response with status code %s.'、response.statusCode ))); } console.log('------------解压响应------------'); zlib.inflateRaw(Buffer.concat(缓冲区), 函数 (gunzipError, body缓冲区) { 如果(gunzipError){ return handleError(gunzipError); } var charset = obtainCharset(response.headers); processResponse(response.headers, bodyBuffer.toString(字符集)); }); }); req.on('data', 函数 (buf) { 缓冲区[buffers.length] = buf; });