【问题标题】:API Data Returning Unicode Characters in Console在控制台中返回 Unicode 字符的 API 数据
【发布时间】:2018-10-31 08:12:15
【问题描述】:

自从过去两天以来,我面临着一个相当令人困惑的问题。我正在开发一个文档管理系统,该系统使用从 SOLR 提取数据的 API。数据大约为 15Mbs,并提取了超过 4000 多个文档的记录。 API 有这种格式的响应 -

{
    "documents": [
        {
            id: 123,
            some_field: "abcd",
            some_other_field: "abcdef"
        },
        {
            id: 124,
            some_field: "abcd1",
            some_other_field: "abcdef1"
        }
    ]
}

在浏览器中一切正常。如果我在 Chrome 或 Firefox 浏览器中点击端点,它会给我正确的输出,并且我能够看到 JSON 输出。

但是,如果我尝试使用 Java 或 JS 代码访问同一个 API 端点 - 响应代码为 200,但控制台(终端或 Eclipse)中的输出显示像 \u0089 \u0078 U+0080 这样的 unicode 字符 - 所有输出都在此方式,并且由于 API 获取了大约 4000 多条记录,控制台有点填充所有这些 un​​icode 字符。

我在浏览器发出的请求和代码之间看到的唯一区别是,在浏览器中我可以看到Content-Encoding : gzip,而我在我编写的代码中找不到这个标头。例如-在JS代码中,通过Chakram框架,我可以检查

expect(response).to.be.encoded.with.gzip

提到了here。但是,这会返回一个失败,说明 expected undefined to match gzip

我在这里缺少什么?这是与编码/解码有关的东西还是完全不同的东西?

编辑 1:在 Chrome 的Network 标签中看到的响应标头:

cache-control: max-age=0, private, must-revalidate, max-age=315360000
content-encoding: gzip
content-type: application/json; charset=utf-8
date: Tue, 22 May 2018 06:07:26 GMT
etag: "a07eb7c1eef4ab97699afc8d61fb9c5d"
expires: Fri, 19 May 2028 06:07:26 GMT
p3p: CP="NON CUR OTPi OUR NOR UNI"
server: Apache
Set-Cookie : some_cookie
status: 200 OK
strict-transport-security: 
transfer-encoding: chunked
vary: Accept-Encoding
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-request-id: abceefr4-1234-acds-100b-d2bef2413r47
x-runtime: 3.213943
x-ua-compatible: chrome=1
x-xss-protection: 1; mode=block

在 Chrome 的 Network 标签中看到的请求标头

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Cookie: some_cookie
Host: abcd.bcd.com
IV_USER: demouser123
IV_USER_L: demouser123
MAIL: demouser@f.com
PERSON_ID: 123
Referer: http://abcd.bcd.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
X-CSRF-TOKEN: some_csrf_token

编辑 2:我正在使用的测试

describe('Hits required API',()=>{

    before(()=>{
        return chakram.wait(api_response = chakram.get(url,options));
    });

    it('displayes response',()=>{
        return api_response.then((t_resp)=>{
            console.log(JSON.stringify(t_resp));
            expect(t_resp).to.have.header('Content-Encoding','gzip');
        });
    });

【问题讨论】:

  • 您能否向我们展示请求的所有标头——请求和响应? (从浏览器复制或使用 cURL)
  • 请参阅编辑@ThomasEdwards
  • 你能告诉我们整个测试吗?
  • 见编辑 2 @ThomasEdwards。此请求是使用 Chakram 发出的
  • t_resp 的控制台日志打印出什么?它是否包含任何标题?

标签: javascript api encoding web-api-testing


【解决方案1】:

这与编码无关。 Web 服务器通常压缩为 gzip 以节省带宽,因为它冗余传输整个 15MB 文件,请参阅本文以了解有关 gZip 及其工作的更多信息 (https://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/)。那么它哪里出错了,它在 chrome 中的工作方式非常简单 chrome 在其 devTools 中有一个内置的 unicode 解析器(甚至是一个 HTML 解析器),它可以向您显示解析的内容,而不是向您显示 wiered 文本(同样可以在响应中看到预览选项卡旁边的选项卡)。为什么你看到奇怪的文字是你在扼杀响应,如果有console.log(JSON.stringify(t_resp));,它将转义特殊字符。你不能使用console.log("response", t_resp); 之类的东西而不在终端中进行字符串化,因为终端没有 JSON 或 unicode 解析器,它只是以文本形式打印。尝试删除该控制台,因为对 15mb 文件进行字符串化是一个代价高昂的过程。

编辑 1:- 如果您仍然想在控制台中输出要做什么。 由于默认情况下 NODE 无法直接解码 gzip(不是使用 chakram,它只是一个 API 测试平台),因此您可以使用 zlib 来执行此操作。请找到示例 sn -p

    const zlib = require('zlib');

describe('Hits required API',()=>{

    before(()=>{
        return chakram.wait(api_response = chakram.get(url,options));
    });

    it('displayes response',()=>{
        return api_response.then((t_resp)=>{
            zlib.gunzip(t_resp, function(err, dezipped) {
                console.log(dezipped);
            });
        });
    });

【讨论】:

  • 希望示例代码有效。虽然没有测试。您可以使用 fiddler 来检查正确的响应,记录整个响应并填充控制台。 @demouser123 ?
  • 管道函数错误 - t_resp.pipe(gunzip); - 管道不是函数。
  • 您现在可以检查...如果可能,您可以提供一个沙盒示例
  • 这将返回 undefined。抱歉,我无法提供沙盒示例:(
【解决方案2】:

尝试使用console.dir 来显示您的价值观

describe('Hits required API',()=>{

    before(()=>{
        return chakram.wait(api_response = chakram.get(url,options));
    });

    it('displayes response',()=>{
        return api_response.then((t_resp)=>{

            console.dir(t_resp, { depth: null });

        });
    });

Console.dir

【讨论】:

  • 不是console.log(JSON.parse(t_resp)); 在终端上显示类似 [Object] 的内容?(如果输出成功解析为对象)
  • @karthik 你是真的。无法识别文本中的高音。 Console.dir 然后可以提供帮助。我现在更新它
  • 不是console.dir和console.log在终端返回一样吗?
  • @karthik 你试过了吗?在节点环境中,它给出了不同的输出。
  • 这给了我与胡言乱语相同的响应
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 2017-11-16
  • 2013-11-20
  • 1970-01-01
  • 2011-08-10
相关资源
最近更新 更多