问题背景
这个报错发生在之前部署的一个前后端分离的项目中。后端使用的Spring Boot,前端使用的JavaScript,前后端交互使用Thymeleaf框架。
现象
项目组的另一个小伙伴说,突然有个页面打不开了,整个页面全空白。我F12打开浏览器发现有如下报错:
问题排查
首先我打开了JavaScript的代码部分,发现报错的是这一行:
这里初步就能判断可能是数据文件(P.s. 这是一个txt文件,里面存放的是JSON格式的数据)的问题了。数据文件可能有些字符串是JavaScript语言的JSON库解析不了的(这个数据文件是一个Python程序生成的)。于是我又看了看数据,发现里面有NaN:
之前我是不知道JSON有哪些是不合法字符的。所以我就查了一下JSON的官方规范文档The JavaScript Object Notation (JSON) Data Interchange Format。其中对于Values的描述如下:
所以问题的原因很明显了:txt数据文件中有NaN,导致JavaScript的JSON库无法对其解析。
Bug复现
为了进一步证明我对于这个问题的原因的猜想是正确的,我尝试复现了这个bug。我在本地用JavaScript、Python两种语言的JSON解析库分别对同一个含有NaN的txt数据文件进行解析。由于我最近一直在写Python,所以先用的Python复现,再用的JavaScript复现的。
数据文件data.txt如下:
{"key": [40.5,NaN]
}
按照JSON规范文档来看,这不是一个合法的JSON数据。
Python解析结果如下:
{'key': [40.5, nan]}
JavaScript解析结果如下:
Error parsing JSON: SyntaxError: Unexpected token N in JSON at position 30at JSON.parse (<anonymous>)
可以看得出来,JavaScript对这种文件的解析确实会报错。而Python居然是不报错的,说明不同语言的JSON解析库的实现差异还挺大的,Python的JSON解析库对于这种不符合JSON规范的不合法字符也能解析。
这里也吸取了一个教训:在复现的时候,一定要保证复现的环境和出现Bug的环境一模一样,不然就会出现我这种换了个语言又能解析的情况。。。
解决方案
在Python程序生成数据NaN的数据后,可以将其替换成其他合法的JSON字符串。
总结
- JSON数据中不是所有字符都是合法的,具体参见JSON官方规范文档:The JavaScript Object Notation (JSON) Data Interchange Format
- 保存任何格式的数据文件时候,尽量保证不要出现该格式文件规范中不合法的字符,除非所有语言都实现了对于这种格式的不合法字符的解析(但这显然不太可能)
- 复现Bug的时候一定要保证复现环境和出现Bug的环境一模一样,包括语言、第三方库的版本等等