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

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

一)现在是什么情况

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. Region-区域(默认和新增)适配器

    Prism内置了几个区域适配器 ContentControlRegionAdapter ItemsControlRegionAdapter SelectorRegionAdapter ComboBox ...

  2. WPF 实现自定义的笔迹橡皮擦

    本文来告诉大家使用比较底层的方法来实现 WPF 的笔迹橡皮擦 在 WPF 里面,对于笔迹来说,应该放在 Stroke 类里面,而不是作为点的集合存储.在 Stroke 类里面将作为管理笔迹的类提供笔迹 ...

  3. 鸿蒙HarmonyOS实战-ArkUI事件(手势方法)

    一.手势方法 应用程序的手势操作是指在移动设备上使用手指或手势进行与应用程序交互的方式.手势操作可以包括点击.滑动.双击.捏合等动作,用于实现不同的功能和操作. HarmonyOS中常见的手势操作及其 ...

  4. Xcode编译WebKit

    下载WebKit源码 1)进入https://webkit.org/ 2)点击页面的 Get Started 进入新页面,如下图所示 3)点击 Getting the code 进入新页面,如下图所示 ...

  5. Java面试题:让依赖注入变得简单,面对@Autowired和@Resource,该如何选择?

    @Autowired和@Resource都是Java Spring框架中的注解,用于实现依赖注入(DI)和控制反转(IoC).它们的区别主要在以下三个方面: 源头不同  @Autowired是Spri ...

  6. .NET 中 Channel 类简单使用

    Channel 是干什么的 The System.Threading.Channels namespace provides a set of synchronization data structu ...

  7. C# 在Excel中添加、应用或删除筛选器 (日期筛选、文本筛选、数字筛选)

    自动筛选器是 Excel 中的一个基本但极其有用的功能,它可以让你根据特定的条件来自动隐藏和显示你的数据.当有大量的数据需要处理时,这个功能可以帮你快速找到你需要的信息,从未更加有效地分析和处理相关数 ...

  8. itest(爱测试) 开源接口测试,敏捷测试管理平台10.2.3发布

    一:itest work 简介 itest work 开源敏捷测试管理,包含极简的任务管理,测试管理,缺陷管理,测试环境管理,接口测试,接口Mock,还有压测 ,又有丰富的统计分析,8合1工作站.可按 ...

  9. vue-devtools

    今天分享个vue的开发者工具,vue2和vue3都可以使用 先来看个效果: 如何安装? 打开官网vue-devtools 选择你需要版本 安装完记得重启下浏览器,不然是没效果的

  10. 「C++」深度分析C++中i++与++i的区别

    大家好,我是Charzie.在C++编程中,i++和++i是两个常见的自增运算符,用于将变量的值增加1(有时与i+=1效果一样).然而,虽然它们的功能看似相似,但在实际使用中却存在显著的区别.本博客将 ...