New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

实战中踩到的 JSON 小坑 #29

Open
cssmagic opened this Issue Sep 26, 2013 · 10 comments

Comments

Projects
None yet
9 participants
@cssmagic
Owner

cssmagic commented Sep 26, 2013

实战中踩到的 JSON 小坑

前端工程师对 JSON 是再熟悉不过了。它语法简单,表现力强,常用于前后端的数据交换。

在实战中,我也遇到过跟 JSON 有关的小坑。

JSON 数据中的 tab 字符

背景

某日在手机版的商品详情页发现了一个隐蔽的 bug,在 iOS 5 下并不会触发,但在当前最新版的 Chrome、Firefox 和 iOS 6+ 下可以重现。故障表现为个别详情页的脚本会挂掉,无法工作。

分析

经过简单的隔离分析之后,把疑点定位到某个 JSON 的解析操作上。该页面的脚本使用了浏览器原生的解析 JSON 的方法 JSON.parse(),但奇怪的是,此方法偶尔会抛出异常,导致后续代码无法执行。(示意如下)

json-traps-in-practice-tab-1

进一步分析发现,与 iOS 5 相比,iOS 6(以及其它较新的浏览器)更严格地遵守了 JSON 规范——如果 JSON 数据中需要出现 tab 字符,必须是经过转义的("\t""\u0009");如果是直接出现,则被认为是非法字符,JSON.parse() 方法会报错。

(相关的讨论可以参见 这里,其中提到了 JSON 的规范 RFC4627。)

后续

JSON 数据中怎么会出现 tab 字符呢?

json-traps-in-practice-tab-2

原来,详情页是以这个 JSON 为载体,将后端数据传递给前端脚本;而这个 JSON 是由 PHP 代码手工拼接的,其中的某个字段是从数据库中直接读取输出的。运营同学在从 Excel 向数据库导入数据时,很可能不小心在数据中混入了一些 tab 字符。

所以,这也算是一个教训,对于那些人工生成的字符数据,还是需要做一定的过滤和校验。在这个案例中,更好方式应该是先把数据存入一个 PHP 数组,再用 json_encode() 将其编码为 JSON 字符串,以确保 JSON 数据的规范性。

JSON 键名中的空格

背景

某天,某后端同学声称,他已经按需求开发完成了一个 API。好的,在浏览器里跑一下,打开 Firebug 查看一下 Ajax 返回的 JSON 数据,看起来没问题。

json-traps-in-practice-space-1

但在渲染这块数据的时候,发现 thumbnail 字段总是无法输出正确的值,总是显示 undefined。难道是拼写有误?我从 Firebug 的 JSON 视图(上图)中复制粘贴过来还是照样出错。真是怪事!

分析

在格式化过的 JSON 视图中看不出问题,那就进一步追查原始数据吧。于是把 Ajax 的返回数据切换到原码视图,搜索 thumbnail 关键字,终于发现问题所在。

json-traps-in-practice-space-2

原来这个字段的键名尾部有一个空格。空格也是键名的一部分,我当然无法输出这个带尾巴的字段了。

后端哥哥,你玩儿我呢吧?

后续

后端哥哥把那个空格去掉,这没什么好说的。


© Creative Commons BY-NC-ND 4.0   |   我要订阅   |   我要打赏

@ajccom

This comment has been minimized.

ajccom commented Sep 26, 2013

后端哥哥空格按的太high

@cssmagic

This comment has been minimized.

Owner

cssmagic commented Sep 26, 2013

@ajccom 哈哈,我估计是他从文档页面中复制字段名时,把空格一起复制过去了。

@ielgnaw

This comment has been minimized.

ielgnaw commented Sep 26, 2013

@ajccom 空格按得太high,这明显是wow玩家。。。。。

@SeniorZhai

This comment has been minimized.

SeniorZhai commented Apr 30, 2014

貌似我也碰到这个错误了

@jierchou

This comment has been minimized.

jierchou commented Sep 25, 2014

哈哈哈。就怕猪一样的队友啊。

@icepy

This comment has been minimized.

icepy commented Sep 25, 2014

我呵呵

@xieranmaya

This comment has been minimized.

xieranmaya commented Sep 3, 2015

同遇到过。。。
调了好久才调出来,主要是JSON.parse不会告诉你问题出在哪一行

@xiexingguang

This comment has been minimized.

xiexingguang commented Nov 29, 2017

这个后端可以统一trim一下 就可以了

@cssmagic

This comment has been minimized.

Owner

cssmagic commented Nov 29, 2017

@xiexingguang
文中的情况不是键值多了空格,而是键名多了空格。键名都是在代码中手写的,不太可能统一 trim 吧?

@zuoqiyin

This comment has been minimized.

zuoqiyin commented Oct 31, 2018

后端忘记了trim,用户按得太high

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment