记一次前端vConsole导致JSON序列化错误排查

晚上8点用户反馈线上服务有问题,立即查日志发现从晚上6点开始突然有大量的错误结构报文请求后台。错误报文为非标准的json报文,错误报文的字符串缺失双引号,例如:

1
2
3
4
5
6
7
{
id:244,
key:bcd2978cfa24b9123325bb780a57e2b1,
outTradeNo:a2ceb251-68e5-459d-84f2-c787f184,
storeId:020109,
uid:400059,
}

初步判断是前端post请求传递的报文序列化出问题了。

本地测试前端代码,可以复现该问题。报文的组装如下:

1
2
3
4
5
6
7
8
9
10
11
12
exchange(id: string, storeId: string, uid: string, key: string): Observable<any> {
let outTradeNo = Guid.newGuid();
const data = {
id: id,
storeId: storeId,
uid: uid,
key: key,
outTradeNo: outTradeNo
}
let body = JSON.stringify(data);
...
}

但是通过JSON.stringify序列化对象时,序列化后的内容错误,序列化的结果丢失了双引号且出现了换行符,如下图:

image

image

debugger查看JSON序列化工具,发现JSON工具多出了一个[[FunctionLocation]]的变量,且值为vconsole.min.js。vconsole为调试工具,但很奇怪地出现在了JSON工具中,于是猜想JSON序列化出问题是不是vconsole的锅。

image

在将项目中的vconsole删除后,序列化的问题解决了,json对象序列化成正确的报文,后台也没有报错误信息。

image

虽然问题解决了,但是原因还没有找到。vconsole很早就已经引用到项目中,但是这次的json序列化异常的问题却是今天第一次出现且最近也没有修改代码。于是突发奇想是不是cdn出问题了?

image

查看vconsole的引用链接,发现明明引用的是vconsole的3.0.0版本,但是cdn却返回的3.2.0版本。

image

查看cdn返回的header信息,也显示cdn在当天的下午2点修改过文件。

image

继续到github找官方链接vConsole,从github上下载3.0.0版本和3.2.0版本的vconsole,引用到项目中后均不会出现这次的json序列化错误的问题,从https://res.wx.qq.com/mmbizwap/zh_CN/htmledition/js/vconsole/3.0.0/vconsole.min.js下载的vconsole则会导致这次的json序列化错误的问题。经对比也发现,cdn返回的3.2.0版本的js文件与github上的3.2.0版本的js文件有差异。

原因似乎就明了了:cdn与当天下午2点把vconsole文件修改成了一个错误版本错误内容的文件,然后项目晚上6点开始出现问题json序列化错误的问题。

最终的解决方案很简单,换cdn。

附上此次cdn返回的错误vconsole文件

更新

2019-1-12 19:41

cdn似乎发现并解决了问题,现在获取到的vconsole为正确的3.0.0版本https://res.wx.qq.com/mmbizwap/zh_CN/htmledition/js/vconsole/3.0.0/vconsole.min.js

image

更新

2019-1-14

官方承认了cdn上的3.2.0版本有问题:issues223

实在抱歉,上周有同事将 3.0.0 版的 CDN 文件换成了 3.2.0 版本,恰好 3.2.0 又有 JSON bug,引起上述问题。
现在已经回退,3.0.0 的 CDN 路径应该不会再拉到 3.2.0 版本了。(已拉到的,可能会有 CDN 缓存,我们稍后会清一次缓存,急的话可通过在 URL 后加任意参数来刷新缓存。)
3.2.0 的 JSON 问题,会在稍后的版本中修复。