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

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

一)现在是什么情况

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;
}

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

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

JS的JSON.parse问题的更多相关文章

  1. JS中JSON.parse和eval的异同

    1.相同点 JSON.parse和eval函数都可将一段json字符串转换为json对象,如: var json = '{"intro":[{"name":&q ...

  2. JS之JSON.parse和JSON.stringify

    这两个函数有兼容性问题, 会报错JSON"未定义 解决方案, 引入json2.js,可以解决浏览器的兼容性 https://link.jianshu.com/?t=https://githu ...

  3. js - SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data jquery-1.9.1.min.js:3:4315

    FF中时不时报这个错, 就近段做项目来看,  一般是我通过 jquery获取form中的参数(或直接获取参数,并通过ajax进行异步请求的时候,如果有错,就抱该错误! 而对应的, 如果在 Google ...

  4. js之json

    关于json不了解的,请点击:http://www.json.org/json-zh.html json对象的属性必须要用双引号,值为字符串类型也只能使用双引号,例:{"name" ...

  5. 你不知道的JSON.stringify和JSON.parse

    json是JavaScript 对象表示法(JavaScript Object Notation),是一种简单的数据格式,类似于XML,其格式为名称/值对,数据用逗号隔开,名称必须用双引号括起来.例如 ...

  6. JSON.stringify,JSON.parse方法

    var obj={name:'zhangsan',age:'18'};/** js对象--->JSON字符串* JSON.stringify(js对象) --转化为--> JSON字符串* ...

  7. arguments.callee 调用函数自身用法----JSON.parse()和JSON.stringify()前端js数据转换json格式

    arguments.callee 调用函数自身用法 arguments.callee 在哪一个函数中运行,它就代表哪个函数. 一般用在匿名函数中. 在匿名函数中有时会需要自己调用自己,但是由于是匿名函 ...

  8. Js中JSON.stringify()与JSON.parse()与eval()详解及使用案例

    JSON(JavaScript Object Notation)是一种轻量级的数据交换格式.因为采用独立于语言的文本格式,也使用了类似于C语言家族的习惯,拥有了这些特性使使JSON称为理想的数据交换语 ...

  9. js数组使用JSON.stringify()和toString()的区别,JSON.parse

    JSON.stringify()中的<br><br>var arr = [1,2,3,4]; console.log(arr.toString()); // 1,2,3,4 a ...

  10. JSON.parse 的用法,在js中用的。也是反序列化用法。

    参数 text 必需. 一个有效的 JSON 字符串. reviver 可选. 一个转换结果的函数. 将为对象的每个成员调用此函数. 如果成员包含嵌套对象,则先于父对象转换嵌套对象. 对于每个成员,会 ...

随机推荐

  1. 如何将本地项目第一次同步到gitee远程

    一,Gitee账号的注册/登录 在gitee登录入口输入相关信息进行注册登录https://gitee.com/signup#lang=zh-CN 二,本地安装git客户端并配置用户信息 1.Git ...

  2. webapp监听手机物理返回键,返回上一页面或者关闭app

    网上抄的做笔记: 1.项目下建文件夹commonFunction->physicBackListener.js 2.这个js文件内复制代码: document.addEventListener( ...

  3. 4.10 + (double)(rand()%10)/100.0

    黑色星期四 坏消息: 没有奥赛课,所以大概率调不出来 CF1479D 好消息: 5k 回来了,调题有望 中午起床直接来的机房,有学科自习就说 氟硫氢 不知道 结果被叫回去了 而且今天班里没水了,趁着大 ...

  4. rpc 和 http的区别

  5. tarjan板子整理

    缩点 stack<int>q; void tarjan(int u) { pre[u]=low[u]=++cnt; q.push(u); vis[u]=1; for(int i=head[ ...

  6. 关于ESLint: Delete `␍`(prettier/prettier) 错误解决方案(3种)

    1.点击VSCode右下角LF/CRLF然后根据弹窗修改成LF即可 2.在.eslintrc.cjs中增加配置 "rules": { "prettier/prettier ...

  7. js RGB转HSV

    function rgb2hsv (r,g,b) { var computedH = 0; var computedS = 0; var computedV = 0; //remove spaces ...

  8. 鸿蒙HarmonyOS实战-Stage模型(卡片数据交互)

    一.卡片数据交互 HarmonyOS卡片数据交互是指在基于鸿蒙操作系统的设备上,卡片界面之间进行数据的传输和交互. HarmonyOS的卡片是一种轻量级的应用界面,可以在设备的屏幕上显示信息和提供操作 ...

  9. centos7中输入ifconfig 没有IP地址

    vmware安装的centos7中没有出现eth0网卡,也没有ip,不能上网,输入ifconfig后如下图 解决办法 1.编辑网卡的配置文件 vi /etc/sysconfig/network-scr ...

  10. WPF显示网络图片的几种方法

    1.利用数据流 1 Image img; 2 byte[] btyarray = GetImageFromResponse(imageUrl); 3 4 //字节数据转流 5 MemoryStream ...