将 JSON 响应转换为 JavaScript 中的正确编码

Converting JSON response into correct encoding in JavaScript

我正在尝试使用来自 API 的数据。我正在使用 request for the API access, but have also tried axios.

const request = require('request')
request('https://remoteok.io/api', function (error, response, body) {
  const data = JSON.parse(body)
  console.log(data)
})

访问网站 remoteok.io/api in a browser, I can see sequences like \u00e2\u0080\u0099. This sequence should be a backtick apostrophe, but when I log to the console in JavaScript or use express 以呈现 res.json(body) 时,我得到的是字符 â€

如何解决这个编码问题? JSON 不应该总是纯 UTF-8 吗?

UPDATE: Here is a simple glitch project that shows the behavior.

我认为这不是错误,您可以使用此扩展程序在浏览器上查看 JSON JSON Viewer

问题出在源数据中:JSON序列"\u00e2\u0080\u0099"不代表右右引号。这里有三个 Unicode 码位,第一个代表“â”,另外两个是控制字符。

您可以在开发控制台中验证这一点,或者通过 运行 下面的代码片段:

console.log(JSON.parse('"\u00e2\u0080\u0099"'));

显然 JSON 的作者混淆了两件事:

  • JSON 以 UTF 编码
  • 一个\u符号表示一个Unicode代码点

第一个表示filestream,将JSON文本编码成字节,应该是UTF编码(首选 UTF8)。第二个与此无关。 JSON 语法允许使用 \u 语法指定 16 位 Unicode 代码点。它无意生成具有 \u 编码序列 1 的 UTF8 字节序列。在定义 JSON 文本时,不应该关心较低级别的 UTF8 字节流编码。

1 我可能需要至少提一下 代理对,但它们确实与 UTF8 无关,但更多关于如何在 JSON.

中编码超出 16 位范围的 Unicode 代码点

因此,尽管 右结束引号 has an UTF8 sequence of E2 80 99,但对于这三个字节中的每一个字节,都不应使用 \u 符号进行编码。

右闭引号 具有 Unicode 代码点 \u2019。所以源 JSON 应该有那个,或者它应该只是字面上的字符 ' (这确实是 字节流 中的 UTF8 序列,但这是一个级别以下JSON)

看看这两种可能性:

console.log(JSON.parse('"’"'));
console.log(JSON.parse('"\u2019"'));

现在呢?

我建议您联系此特定 API 的服务提供商。他们的 JSON 生产服务中有一个错误。

无论您做什么,都不要尝试在使用此服务的客户端中修复此问题,尝试识别此类格式错误的序列,并将它们替换为就好像这些字符表示 UTF8 字节一样。这样的修复将难以维护,甚至可能会出现 误报