淺談 JSON 那些被轉義的字符們


其實,之前我一直以為 JSON 會把 ASCII 可顯示字符以外的統統轉義為 Unicode,
直到有一次我用 JSON.stringify 才發現,其實是 PHP 為我們想的太周到了。

我以前是一位 phper,所以處理 json 只要 json_encode 就可以把數組轉為 json 數據了,非常方便。

可以看到,默認就是把所有 ASCII 可顯示字符以外的統統轉義為 Unicode。

這樣做有什么好處呢?
大家在調用 jsonp 接口或者調用js文件的時候,由於文件編碼不同導致的亂碼問題,應該不會陌生吧。
如果你的文件出現了非英文字符,如果調用時文件編碼不一致,則會出現亂碼情況。
很多新手朋友應該都糾結過這種問題吧。

但是如果把那些字符轉義為 Unicode 之后,無論文件編碼是否一致,都不會出現亂碼。
這就是為什么 PHP 會默認編碼為 Unicode 的原因,她為我們想的太周到了。

當然如果你非要直接顯示那些字符,也是OK的,第二個參數加上 JSON_UNESCAPED_UNICODE 即可。
但是這個參數 PHP 5.4.0 才開始支持。

那么 JSON.stringify 會轉義哪些呢?
json2.js 第 351 行可以看到這個正則。

escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;

也就是說 JSON 只會轉義這部分字符為 unicode,我們來簡單測試下吧。

console.log( JSON.stringify("\x00 \x0a") );

點運行后,可以看到 \x00 被轉義為 \u0000\x0a 卻被專為了 \n
\n 這些特殊字符的轉換在剛才那個正則下面就可以看到了。

但是你測試字符 \ufeff 的時候會發現 firefox 和 chrome 根本沒轉義。
確實,,好像只有 json2 為我們轉義了。

為什么原生 JSON.stringify 這么多字符都沒轉義,難道他就沒為我們考慮兼容問題么?
其實我覺得,這個問題可以不要考慮,因為你不會直用靜態的頁面為其他站點提供接口之類的。
往往只是自己內部用而已,就算提交給后台,一個項目下編碼也是一樣的,所以內部不需要考慮那些兼容問題。
就好比在自己老家,難道你要普通話或英文跟他們交流么?
直接用方言交流才更加流暢。

當然這個只是我個人觀點,也不知道寫js引擎的大神是怎么想的。

我們來遍歷下原生 JSON 對 \u000-\uffff 這些字符的轉義情況吧。

for (var i = 0, str = '', arr = []; i < 0xffff; i++) {
    str = JSON.stringify(String.fromCharCode(i));
    str.indexOf("\\") > -1 && arr.push(str);
}
console.log(arr.join(", "));

我的 chrome 34 得到的結果是

["\u0000", "\u0001", "\u0002", "\u0003", "\u0004", "\u0005", "\u0006", "\u0007", "\b", "\t", "\n", "\u000b", "\f", "\r", "\u000e", "\u000f", "\u0010", "\u0011", "\u0012", "\u0013", "\u0014", "\u0015", "\u0016", "\u0017", "\u0018", "\u0019", "\u001a", "\u001b", "\u001c", "\u001d", "\u001e", "\u001f", "\"", "\\"];

好了,今天的分享就這些了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM