JSON.parse中包含特殊字符串无法转换问题详解

版权声明:原创博文,转载请注明出处~ https://blog.csdn.net/She_lock/article/details/82909566

一、问题

今天小程序线上,有客户反映在购买一本名为《习近平的七年知青岁月》的书籍时,出现点击提交订单时页面数据丢失的情况。

经过反复排查,发现是由于这本书籍查询出来的实体中包含一个字段,字段的值包含了特殊字符“=”号。而这个实体对象,在小程序端,我们是通过 JSON.stringifyJSON.parse来在页面之间传递对象数据的,众所周知,JSON.parse这个js方法,解析特殊的字符串会抛错。

那么问题就来了,这也是广大前端程序员会埋怨的一个坑:怎么解决JSON.parse无法解析特殊字符串的问题?

二、基础详解

JSON.stringify

用于将 JavaScript 值转换为 JSON 字符串。

语法:

JSON.stringify(value[, replacer[, space]])

参数说明:

  • value:必需, 要转换的 JavaScript 值(通常为对象或数组)。

  • replacer:可选。用于转换结果的函数或数组。如果 replacer 为函数,则 JSON.stringify 将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:""。如果 replacer 是一个数组,则仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。

  • space:可选,文本添加缩进、空格和换行符,如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 也可以使用非数字,如:\t。

返回值:返回包含 JSON 文本的字符串。

用法:

  		let order = [];
        order.push(goods);
        let orderJsonStr = JSON.stringify(order);  //将order对象转化为字符串

JSON.parse

用于将一个 JSON 字符串转换为对象。

语法

JSON.parse(text[, reviver])

参数说明:

  • text:必需, 一个有效的 JSON 字符串。
  • reviver: 可选,一个转换结果的函数, 将为对象的每个成员调用此函数。

返回值:返回给定 JSON 字符串转换后的对象。

用法:

dataSoure = JSON.parse(options.orders);  //将order字符串转化为对象

encodeURIComponent

把字符串作为 URI 组件进行编码。

语法:

encodeURIComponent(URIstring)

参数说明:

  • URIstring:必需。一个字符串,含有 URI 组件或其他要编码的文本。

返回值:URIstring 的副本,其中的某些字符将被十六进制的转义序列进行替换。

说明:该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:- _ . ! ~ * ' ( )
其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。

例子:

<script type="text/javascript">

document.write(encodeURIComponent("http://www.w3school.com.cn"))
document.write("<br />")
document.write(encodeURIComponent("http://www.w3school.com.cn/p 1/"))
document.write("<br />")
document.write(encodeURIComponent(",/?:@&=+$#"))

</script>


输出:
http%3A%2F%2Fwww.w3school.com.cn
http%3A%2F%2Fwww.w3school.com.cn%2Fp%201%2F
%2C%2F%3F%3A%40%26%3D%2B%24%23

encodeURI

把字符串作为 URI 进行编码。

语法:

encodeURI(URIstring)

参数说明:

  • URIstring :必需。一个字符串,含有 URI 或其他要编码的文本。

返回值:URIstring 的副本,其中的某些字符将被十六进制的转义序列进行替换。

说明:该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( )。该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 函数是不会进行转义的:;/?:@&=+$,#

例子:

<script type="text/javascript">

document.write(encodeURI("http://www.w3school.com.cn")+ "<br />")
document.write(encodeURI("http://www.w3school.com.cn/My first/"))
document.write(encodeURI(",/?:@&=+$#"))

</script>

输出:
http://www.w3school.com.cn
http://www.w3school.com.cn/My%20first/
,/?:@&=+$#

decodeURIComponent

decodeURIComponent() 函数可对 encodeURIComponent() 函数编码的 URI 进行解码。

语法:

decodeURIComponent(URIstring)

参数说明:

  • URIstring : 必需。一个字符串,含有编码 URI 组件或其他要解码的文本。

返回值:URIstring 的副本,其中的十六进制转义序列将被它们表示的字符替换。

例子:

<script type="text/javascript">

var test1="http://www.w3school.com.cn/My first/"

document.write(encodeURIComponent(test1)+ "<br />")
document.write(decodeURIComponent(test1))

</script>

输出:
http%3A%2F%2Fwww.w3school.com.cn%2FMy%20first%2F
http://www.w3school.com.cn/My first/

decodeURI

decodeURI() 函数可对 encodeURI() 函数编码过的 URI 进行解码。

语法:

decodeURI(URIstring)

参数说明:

  • URIstring: 必需。一个字符串,含有要解码的 URI 或其他要解码的文本。

返回值:URIstring 的副本,其中的十六进制转义序列将被它们表示的字符替换。

例子:

<script type="text/javascript">

var test1="http://www.w3school.com.cn/My first/"

document.write(encodeURI(test1)+ "<br />")
document.write(decodeURI(test1))

</script>


输出:
http://www.w3school.com.cn/My%20first/
http://www.w3school.com.cn/My first/

三、解决办法

从上面的基础函数了解到,encodeURIComponent方法包含的解码特殊字符串包含了我线上遇到的字符“=”号,所以解决办法就来了。JSON.stringify 后编码,JSON.parse 前转码。

编码:

        let order = [];
        order.push(goods);
        let orderJsonStr = JSON.stringify(order);
        
        //encodeURIComponent(orderJsonStr) 进行编码
        wx.navigateTo({
			url: '../ConfirmOrder/ConfirmOrder?orders=' + encodeURIComponent(orderJsonStr)
        })

转码:

 onLoad: function (options) {
 		
		let order = JSON.parse(decodeURIComponent(options.orders)); //转码
		...
}

猜你喜欢

转载自blog.csdn.net/She_lock/article/details/82909566