JSON.stringify不应该转义Unicode字符吗?

时间:2012-09-04 21:23:06

标签: javascript json unicode

我在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();
​

虽然我希望非ASCII字符按照JSON spec转义为\ 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ška • Poišči • Cari • חיפוש • Търсене • Іздеу • Bilatu • Suk • Bilnga • Traži • खोजें\n"}

我正在使用Chrome,因此它应该是原生JSON.stringify实施。页面的编码是UTF-8。不应该转义非ASCII字符吗?

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

5 个答案:

答案 0 :(得分:32)

JSON spec不要求从unicode字符转换为转义序列。 “除”或\或控制字符。“之外的任何UNICODE字符都被定义为有效的JSON序列化字符串:

json string format

答案 1 :(得分:5)

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

但是,如果您使用utf-8编码保存HTML文件,但处理 utf8 字符串可能会很奇怪,但不要将其声明为 utf8 文件。

例如:

<!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"

答案 2 :(得分:2)

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

如果您想要更安全或明确地以不同的编码(即纯ASCII)发送JSON,则可以转义unicode字符,但这是违反建议的。

答案 3 :(得分:1)

你的主张是不正确的。 JSON字符串由unicode代码点组成(除了&#39;&#39;&#39;&#39;&#39;&#39;),这些都是。整个JSON文档可以编码为UTF-8,UTF-16或UTF-32,由制作人自行决定。 另外,字符串可以包含转义序列,它提供替代形式的命名代码点,替代字面包含它们。

如果两者之间的区别仍然存在,那么这里有两种不同的方式在JSON中编写相同字符串的示例:

  • "A"

  • "\u0041"

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

答案 4 :(得分:0)

独立的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!"}"

希望这会有所帮助。