14

我有一个简单的 UTF-8 测试页面,其中包含多种不同语言字母的文本被字符串化为 JSON:

http://jsfiddle.net/Mhgy5/

HTML:

<textarea id="txt">
検索 • Busca • Sök • 搜尋 • Tìm kiếm • Пошук • Cerca • Søk • Haku • Hledání • Keresés • 찾기 • Cari • Ara • جستجو • Căutare • بحث • Hľadať • Søg • Serĉu • Претрага • Paieška • Poišči • Cari • חיפוש • Търсене • Іздеу • Bilatu • Suk • Bilnga • Traži • खोजें
</textarea>
<button id="encode">Encode</button>
<pre id="out">
</pre>

JavaScript:

​$("#encode").click(function () {
    $("#out").text(JSON.stringify({ txt: $("#txt").val() }));
}).click();
​

虽然我希望根据JSON 规范将非 ASCII 字符转义为 \uXXXX ,但它们似乎没有受到影响。这是我从上述测试中得到的输出:

{"txt":"検索 • Busca • Sök • 搜索 • Tìm kiếm • Пошук • Cerca • Søk • Haku • Hledání • Keresés • 찾기 • Cari • Ara • جستجو • Căutare • بحث • Hľadať • Søg • Serĉu • Претраг • Paie • Poišči • Cari • חיפוש • Търсене • Іздеу • Bilatu • Suk • Bilnga • Traži • खोजें\n"}

我正在使用 Chrome,所以它应该是本机JSON.stringify实现。页面的编码是 UTF-8。非ASCII字符不应该被转义吗?

首先让我参加这个测试的是,我注意到jQuery.ajax当非 ASCII 字符出现在数据对象属性中时,它们似乎并没有转义它们。这些字符似乎以 UTF-8 传输。

4

5 回答 5

36

JSON 规范不要求将 unicode 字符转换为转义序列。"除 " 或 \ 或控制字符之外的任何 UNICODE 字符。" 被定义为有效的 JSON 序列化字符串:

json字符串格式

于 2012-09-04T21:25:31.667 回答
5

您的问题的简短回答是否定的;JSON.stringify不应该逃避你的字符串。

虽然,如果您使用编码保存 HTML 文件但不将其声明为utf8文件,那么处理utf8字符串可能看起来很奇怪。utf-8

例如:

<!doctype html>
<html>
    <head>
        <title></title>
        <script>
            var data="árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP";
            alert(JSON.stringify(data));
        </script>
    </head>
</html>

这会引起警觉"árvíztűrÅ‘ tükörfúrógép ÃRVÃZTÅ°RÅ TÃœKÖRFÚRÓGÉP"

但是,如果您将以下行添加到标题中:

<meta charset="UTF-8">

然后,警报将是人们所期望的:"árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP".

于 2014-12-02T14:37:30.233 回答
3

不,JSON 的首选编码是 UTF-8,因此这些字符不需要转义。

如果您想更安全或以不同的编码(即纯 ASCII)显式发送 JSON,则允许您转义 unicode 字符,但这不符合建议。

于 2012-09-04T21:26:11.210 回答
3

确实 JSON.stringify 不会转义 utf8:

JSON.stringify({a:"Привет!"})
{"a":"Привет!"}

但是当我通过 Perl DBD::Mysql 存储该 JSON 然后将其检索回来时,我遇到了一个问题。我发现按照建议通过 \uXXXX 转义所有非 ascii 和不可见字符会更安全。这是如何

function jsonEscapeUTF(s) {return s.replace(/[^\x20-\x7F]/g, x => "\\u" + ("000"+x.codePointAt(0).toString(16)).slice(-4))}

jsonEscapeUTF(JSON.stringify({a:"Привет!"}))
"{"a":"\u041f\u0440\u0438\u0432\u0435\u0442!"}"

希望它会有所帮助。

于 2020-10-17T09:51:00.863 回答
1

你的说法是不正确的。JSON 字符串由 unicode 代码点('"' 和 '\' 除外)组成,仅此而已。整个 JSON 文档可以根据生产者的判断以 UTF-8、UTF-16 或 UTF-32 编码。此外,字符串可以包含转义序列,提供一种命名代码点的形式,而不是按字面意思包含它们。

如果您仍然无法区分两者之间的区别,这里有一个示例,说明了在 JSON 中编写相同字符串的两种不同方式:

  • "A"

  • "\u0041"

两个版本都代表相同的字符串,由单个代码点 U+41 组成,即A.

于 2012-09-04T21:29:11.457 回答