JavaScript JSON.parse 不支援斷行,TAB等字元,例如 \n, \r, \t, \b 這些特殊字元,如果你的 json string 有使用到這些字元, JavsScript 就會吐出錯誤訊息,例如下面這個 JS 程式碼,我先宣告一個含有斷行符號的字串 "\n",再用 JSON.parse 將字串轉成 JSON ,這個 sample code 在瀏覽器下執行會出現 error : SyntaxError: Unexpected token 。
- <script>
- var s = '{"test": "a\nb"}';
- var ret = JSON.parse(s);
- console.log(ret);
- </script>
當然前端很少會直接宣告一個字串,然後又對他做 JSON.parse ,這個問題會發生在後端回傳一個 JSON string ,交給前端做 JSON.parse ,例如 PHP 可能會這樣做:
- <?php
- $res = array(
- "message" => "Got a error,\n error message: unknown",
- );
- echo json_encode($res);
- // Output: {"message":"Got a error,\n error message: unknown"
這個範例拿到的 JSON string 含有 "\n",只要 JavaScript 對這個 string 做 JSON.parse 馬上就會中 JS Error。
解決方案
1. 寫 JavaScript 時最好有個習慣,只要用到 JSON.parse 就一定要加上 try catch 機制,我常常遇到特殊字元,造成 JSON.parse fail 的情形,未知的問題比我們想像中的還要多,所以一定要有 parse fail 的處理方式。
2. PHP 對 array 做兩次 json_encode,第二次的 json_encode 會把所有的符號加上跳脫字元,這樣 JavaScript 再做 json parse 時就能夠正確處理斷行,TAB 等符號,要注意,兩次 json_encode 之後所得到的結果會是一個被雙引號括起來的 "string" ,只要先把字串左右兩邊的雙引號移除,JavaScript 只對它做一次 JSON.parse 就能得到 JSON format,不用 JSON.parse 兩次。
- <?php
- $res = array(
- "message" => "Got a error,\n error message: unknown",
- );
- $a = json_encode(json_encode($res));
- //Output : "{\"message\":\"Got a error,\\n error message: unknown\"}"
3. 第三種解法是手動把有問題的符號加上跳脫字元
- <?php
- function json_stringify($json) {
- if (is_array($json)) $json = json_encode($json);
- $search = array('\\', "\n", "\r", "\f", "\t", "\b", "'") ;
- $replace = array('\\\\', "\\n", "\\r","\\f","\\t","\\b", "'");
- return str_replace($search, $replace, $json);
- }
- $res = array(
- "message" => "Got a error,\n error message: unknown",
- );
- $a = json_stringify($res);
- echo <<<HTML
- <script>
- var s = JSON.parse('$a');
- console.log(s);
- </script>
- HTML;