5

Javascript解析JSON字符串报错:parse failed: SyntaxError: Unexpected token n in...

 2 years ago
source link: https://xmanyou.com/javascript-json-parse-failed-syntax-error-unexpected-token-in-json/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
8 June 2021 / 开发笔记

Javascript解析JSON字符串报错:parse failed: SyntaxError: Unexpected token n in JSON

有个JavaScript对象obj,其中一个属性值为另一个对象child的JSON stringify后得到的JSON字符串。

大概是这样子

	var child = {
		number: 123,
		string: "abc"
	};
	var childValue = JSON.stringify(child);
	var obj = {
		data: [
			{
				key: "mykey",
				value: childValue
			}
		]
	}

obj对象的数据被JSON化后存储在服务器上,读取时,服务器也用JSON格式发送obj对象数据。

但是,奇怪的是,在对服务端获取的obj JSON数据进行解析时,报错了

parse failed:  SyntaxError: Unexpected token n in JSON at position 54

这是为什么呢?

为了解决这个问题,写了一个简单的js测试用例,如下。

try{
	var child = {
		number: 123,
		string: "abc"
	};
	var childValue = JSON.stringify(child);
	var obj = {
		data: [
			{
				key: "mykey",
				value: childValue
			}
		]
	}

	var objJson = JSON.stringify(obj);

	console.info("child json ===> ", childValue);
	console.info("=============================\n");

	console.info("obj json ===> ", objJson);
	console.info("=============================\n");
	
	var b = JSON.parse(objJson);
	console.info("obj parse from json => ", b);
	console.info("=============================\n");


	var objJson3 = `
	{
		"data":[
			{
				"key":"mykey",
				"value":"{\\\"number\\\":123,\\\"string\\\":\\\"abc\\\"}"
			}]
		}
	`;

	var objJson2 = `
	{
		"data":[
			{
				"key":"mykey",
				"value":"{\"number\":123,\"string\":\"abc\"}"
			}]
		}
	`;

	var c = JSON.parse(objJson3);
	console.info("obj3 parse from json => ", c);
	console.info("=============================\n");

	c = JSON.parse(objJson2);
	console.info("obj2 parse from json => ", c);
	console.info("=============================\n");

	// var v = b.data[0].value;
	// console.info("value: ", v);
	// var vo = JSON.parse(v);
	// console.info("value to object: ", vo);
}catch(e){
	console.info("parse failed: ",e);
}
node test.js
child json ===>  {"number":123,"string":"abc"}
=============================

obj json ===>  {"data":[{"key":"mykey","value":"{\"number\":123,\"string\":\"abc\"}"}]}
=============================

obj parse from json =>  { data: [ { key: 'mykey', value: '{"number":123,"string":"abc"}' } ] }
=============================

obj3 parse from json =>  { data: [ { key: 'mykey', value: '{"number":123,"string":"abc"}' } ] }
=============================

parse failed:  SyntaxError: Unexpected token n in JSON at position 54
    at JSON.parse (<anonymous>)
    at Object.<anonymous> (/Users/zhangzhibin/Documents/mygit/temp/test.js:54:11)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47

发现,从服务端读取的obj数据是objJson2,该数据中,child的json串中增加了一些转义字符(由斜杆\开头)。
这是正常的,JSON字符串需要对特殊字符进行转义才能保存。

而报错的位置,正是第一个转移字符:
json-parse-failed-syntax-error-unexpected-token-01

仔细分析一下,JavaScript的JSON.parse在解析时,可能先对字符串中的转义字符进行转义,其中

\" => "

所以,objJson2等同于

	var objJson2 = `
	{
		"data":[
			{
				"key":"mykey",
				"value":"{"number":123,"string":"abc"}"
			}]
		}
	`;

而这,显然不是一个合法的JSON串了。

同理,对于objJson3,对转义字符进行一次处理:

\\ => \
\" => "
	var objJson3 = `
	{
		"data":[
			{
				"key":"mykey",
				"value":"{\"number\":123,\"string\":\"abc\"}"
			}]
		}
	`;

这是一个合法的嵌套了JSON串的JSON串。

如何处理这种情况

有几个方案:

    1. 对特殊字符串进行编码
      例如,在保存的时候,将内嵌的json串进行base64编码,在读取后,进行base64解析。
    1. 在读取时对转义字符进行二次转义
      例如,将服务端读取的字符串中
\ 替换成 \\

注意,如果在java中使用这种方案,需要

strBsf.replaceAll("\\\\", "\\\\\\\\")

参考: https://www.cnblogs.com/yanduanduan/p/7157877.html

阿斌

Read more posts by this author.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK