JS的JSON.parse问题

这个问题,已经有非常多人说过,而且由来已久。

大家都提供了不少的解决方法,但是都不够彻底。

 

一)现在是什么情况

1.使用SpringMvc+ModelAndView+jsp传递值

由于业务需要,通过mv向jsp传递值p,之后jsp解析p,其中p是JSON字符串。

这个串在java中没有问题,但是在jsp中使用JSON.parse的时候遇到了问题,这个问题就是经典的转义字符问题

2.在html/jsp中直接定义字面量json字符串的时候,parse问题,情况同第1种

 

二)如何解决

1.如果是规避,那么有许多种方法,例如放弃mv传值方式,或者java后台处理好,或者避免使用字面量定义json字符串。不过本文不阐释这个。

2.在使用字面量之前,先转换。

本文通过例子来看看第2种的解决方案

 

三)解决例子



<html>

<head>     <meta charset="utf-8"> `     <title>this a simple 特别字符测试</title>     <style>         #dDivMain {             text-align: center;             margin-left: 20%;             margin-right: 20%;             margin-top: 45px;         }                  span {             word-wrap: break-word;             word-break: break-all;             text-align: left;             display: block;         }                  table {             width: 100%;             display: inline-table;             border-spacing: 0rem;         }                  th {             background-color: blue;             color: yellow;         }                  th,         td {             border-style: solid;             border-width: 1px;             border-color: green;         }                  textarea {             word-break: break-all;             word-wrap: break-word;             overflow-y: scroll;             width: 50%;         }     </style> </head>
<body>     <div id="dDivMain">         <span>js中存在一些异常的字符,这些字符必须使用转义的方式才可以表达         </span>         <hr>         <span>以下是常见的转义字符:</span>         <table>             <thead>                 <th>字符</th>                 <th>含义</th>             </thead>             <tbody>                 <tr>                     <td>\'</td>                     <td>单引号</td>                 </tr>                 <tr>                     <td>\"</td>                     <td>双引号</td>                 </tr>                 <tr>                     <td>\&</td>                     <td>和号</td>                 </tr>                 <tr>                     <td>\\</td>                     <td>反斜杠</td>                 </tr>                 <tr>                     <td>\n</td>                     <td>换行</td>                 </tr>                 <tr>                     <td>\r</td>                     <td>回车符</td>                 </tr>                 <tr>                     <td>\t</td>                     <td>制表符</td>                 </tr>                 <tr>                     <td>\b</td>                     <td>退格</td>                 </tr>                 <tr>                     <td>\f</td>                     <td>换页</td>                 </tr>             </tbody>         </table>         <span>1)这些转义字符如果是普通应用,那么脚本不会报告错误</span>         <span>2)但是如果直接书写,用作一些JSON处理,就会异常</span>         <hr>         <div>             <input type="button" value="显示JSON属性-From Server" onclick="getJsonValue()">             <input type="button" value="显示JSON属性-Local String" onclick="getJsonValueFromLocal()">             <input type="button" value="显示JSON属性-From Object" onclick="getJsonValueFromObject()">         </div>         <div id="dDivContent" style="display: flex;margin-top: 10px;">             <textarea rows="10" cols="50" id="dTjsonstr"></textarea>             <textarea rows="10" cols="50" id="dTjsonValue"></textarea>         </div>     </div>
</body> <!-- <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> --> <script src="jquery-3.6.0.js"></script> <script>     function getJsonValue() {         $.get("http://localhost:9999/map/getJson", function(response) {             let str = JSON.stringify(response);             let now = new Date();             $("#dTjsonstr").val(now + "\najax解析\n" + str);         });     }
    function getJsonValueFromLocal() {         let jstr = '{"address":"中国\"","sex":"\r男\r\n"}';         //let jstr = '{"address":"中国","phone":"123888&","sex":"男\\r\\n","name":"luzhifei\\t"}';         jstr = replaceEscapeChar(jstr);         let jo = JSON.parse(jstr, function(k, v) {             console.log(k + ":" + v);             return v;         });         let txt = jo.address;         $("#dTjsonValue").val(txt);     }
    function getJsonValueFromObject() {         let jo = {             name: "luzhifei\t",             sex: "男\n",             address: "中国",             phone: "13333&&"         }         let txt = jo.name + jo.sex + jo.address;         $("#dTjsonValue").val(txt);     }
    /**      * @description 最彻底的方法是分解之后替换再合并      */     function replaceEscapeChar(sSource) {         const escapeCharArr = [{             key: '\"\"',             value: '\\"\"'         }, {             key: '\t',             value: '\\t'         }, {             key: '\n',             value: '\\n'         }, {             key: '\r',             value: '\\r'         }, {             key: '\t',             value: '\\t'         }];         let tmpStr = sSource;         for (let i = 0, len = escapeCharArr.length; i < len; i++) {             let arr = tmpStr.split(escapeCharArr[i].key);             tmpStr = arr.join(escapeCharArr[i].value);         }         return tmpStr;     } </script>
</html>

 

运行结果如下图:

JS的JSON.parse问题

这个例子说明了3个问题:

a)使用ajax接受的JSON对象,不存在解析问题

b)如果使用简单的对象定义方式,那么不存在异常字符问题

c)使用mv传递(本例没有示范)和字面量定义json字符串的时候,可以使用替换的方式解决parse问题

例子中有意义的代码如下:

function replaceEscapeChar(sSource) {
        const escapeCharArr = [{
            key: '\"\"',
            value: '\\"\"'
        }, {
            key: '\t',
            value: '\\t'
        }, {
            key: '\n',
            value: '\\n'
        }, {
            key: '\r',
            value: '\\r'
        }, {
            key: '\t',
            value: '\\t'
        }];
        let tmpStr = sSource;
        for (let i = 0, len = escapeCharArr.length; i < len; i++) {
            let arr = tmpStr.split(escapeCharArr[i].key);
            tmpStr = arr.join(escapeCharArr[i].value);
        }
        return tmpStr;
    }

 

不过我们希望,以后的浏览器升级之后,程序员不用那么辛苦了。

至少不要幸苦大家,而只是小小麻烦下浏览器厂商!

 

上一篇:golang time.Parse转化后时间加8小时


下一篇:报错py2neo.errors.ClientError: [Request.InvalidFormat] Could not parse the incoming JSON