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;
回應 (Leave a comment)