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>
运行结果如下图:

这个例子说明了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; }
不过我们希望,以后的浏览器升级之后,程序员不用那么辛苦了。
至少不要幸苦大家,而只是小小麻烦下浏览器厂商!
本文来自博客园,作者:正在战斗中,转载请注明原文链接:https://www.cnblogs.com/lzfhope/p/15201737.html
 
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号