如何ad-hoc解码/解压缩nock刻录机产生的输出,以便我们可以将响应视为文本?我想我们不明白响应是否是gzip压缩和/或编码
当我们将它加载到nock中时,该对象可以找到,并且我们的测试表现得像我们期望的那样。要查看API生成的内容,我们必须将日志语句放在实现文件中。
我们正在录制并保存JSON响应:
nock.recorder.rec({output_objects: true, dont_print: true});
JSON.stringify(nock.recorder.play())
我们的文件如下:
[
{
"scope": "https://some.api.com:443",
"method": "POST",
"path": "/auth?key=some_key",
"body": {
"logonId": "user@api.com",
"logonPassword": "secret"
},
"status": 400,
"response": [
"1f8b0800000000000000458cbd6ac34010067b3fc5c735691263bb741344ec42f827420a492916692d1d9cb461f71c218cdf3d97266e6786b92d00c7aaa205290d1c59cd6d71bb3fff8b376939a1cd6abd7ac003cf89b97a5f96757efecc8ef9aede9fb2fc586455f5f55eeedca33db119757f0f5704266334a2ca4d44ec19170941263f76f06657b62dd6cb2af919ec9357cc7255f0cb403e4014df643689b6687d3b3e450c149b1e534f1113a3a71f868cb8f8c04b7ca48b8fa08efcf8ea16f75fa1776d91ee000000"
],
"headers": {
"cache-control": "no-store, no-cache, must-revalidate",
"content-encoding": "gzip",
"content-type": "application/json",
"transfer-encoding": "chunked",
"connection": "Close"
}
}
]
答案 0 :(得分:1)
来自http请求的响应将作为gzip压缩数据返回,由content-encoding
标头指示。 Nock将此数据保存为十六进制编码的缓冲区字符串。
您可以使用以下实用程序将这些磁带转换为json:
var zlib = require('zlib');
var fs = require('fs');
var argv = process.argv.slice(2);
var path = require('path');
var filename = path.resolve(argv[0]);
var file = fs.readFileSync(filename, { encoding: 'utf8' });
var cassettes = JSON.parse(file);
cassettes.forEach(function (cassette) {
if (cassette.headers['content-encoding'] !== 'gzip') {
return;
}
var response = new Buffer(cassette.response[0], 'hex');
var contents = zlib.gunzipSync(response).toString('utf8');
cassette.response = JSON.parse(contents);
delete cassette.headers['content-encoding'];
});
fs.writeFileSync(filename, JSON.stringify(cassettes, null, 2), { encoding: 'utf8' });
请注意,这将覆盖原始磁带,并将所有gzip请求转换为json。另请注意,我没有检查内容类型,因此如果您的响应不是json,则需要对此进行调整。
答案 1 :(得分:0)
Nock将压缩(压缩)的响应序列化为“十六进制缓冲区”; 幸运的是,xxd可以将十六进制缓冲区还原为二进制数据,可以将其压缩以获取纯json文本。
总结:
echo <YOUR-HEX-BUFFER-HERE> | xxd -r -p | gunzip
参考所涉及的示例:
$ echo 1f8b0800000000000000458cbd6ac34010067b3fc5c735691263bb741344ec42f827420a492916692d1d9cb461f71c218cdf3d97266e6786b92d00c7aaa205290d1c59cd6d71bb3fff8b376939a1cd6abd7ac003cf89b97a5f96757efecc8ef9aede9fb2fc586455f5f55eeedca33db119757f0f5704266334a2ca4d44ec19170941263f76f06657b62dd6cb2af919ec9357cc7255f0cb403e4014df643689b6687d3b3e450c149b1e534f1113a3a71f868cb8f8c04b7ca48b8fa08efcf8ea16f75fa1776d91ee000000 \
> | xxd -r -p \
> | gunzip
{
"errorParameters": {},
"errorCode": 2010,
"errorKey": "_ERR_INVALID_EMAILPASSWORD",
"errorMessage": "Please correct the following issues: 1.Sorry either your e-mail or password didn't match what we have on file. Try it again?"
}
目前,我正在回答有关nock项目的积极讨论和建议,并且可能在将来的发行版中对此进行更改;参考:
答案 2 :(得分:0)
聚会晚了一点,但是使用佛朗哥·隆迪尼(Franco Rondini)和ChiperSoft的回答,我想到了:
const zlib = require('zlib');
// Goes from a hex representation of gzipped binary data to an object
module.exports.decode = input => {
if (typeof input.join === 'function') {
input = input.join('');
}
const tempBuffer = Buffer.from(input, 'hex');
const unzippedBuffer = zlib.gunzipSync(tempBuffer);
const contents = unzippedBuffer.toString('utf8');
return JSON.parse(contents);
};
// Goes from an object to a zipped buffer encoded in hex
module.exports.encode = input => {
const inputAsString = JSON.stringify(input);
const tempBuffer = Buffer.from(inputAsString);
const zippedBuffer = zlib.gzipSync(tempBuffer);
return zippedBuffer.toString('hex');
};
这可能不是完美的,但能够用对象即时替换答复很有帮助。
答案 3 :(得分:0)