json编码为啥要转义斜杠?

json编码转义引号比较好理解,验证utf8编码也比较好理解,但为啥要转义斜杠,而且各种库,各种框架的行为还不一样。

比如js的JSON.stringify()不做转义,但解析时能够支持有转义后的结果,python的标准库json也一样,

>>> json.dumps({'name': 'abc</abc'})
>>> '{"name": "abc</abc"}'

>>> json.loads('{"name":"abc<\\/abc"}')
>>> {u'name': u'abc</abc'}

>>> json.loads('{"name":"abc<\/abc"}')
>>> {u'name': u'abc</abc'}

>>> json.loads('{"name":"abc</abc"}')
>>> {u'name': u'abc</abc'}

但像tornado框架仅仅转义</为<\/,而php标准库将所有/转义为\/,ujson也一样,将所有/转义为\/,那为何要将斜杠进行转义呢,斜杠对json本身的格式并无干扰,而且为何各种语言,各种库的处理行为还不一样呢?!

查了很多说法,主要是因为json常常和javascript在一起,而<script>和</script>标签之间要求不能有</,解释器一遇到</就认为js中止了。节省开销同时兼顾安全的框架,就会只替换</,而多数框架和库会把所有的/替换成\/,而这种替换本身只是为配合js做的兼容措施,其实很多时候我们使用json并不会放在<script>标签中,所以也有很多库并不会做斜杠转义,如python的标准库。

ujson和json对比

总体来说,ujson比标准库里的json好太多,ujson能编码得更正确:

>>> ujson.dumps({'a', 'b', 'c'})
>>> '["a","c","b"]'

>>> ujson.dumps({'time': datetime.datetime.now()})
>>> '{"time":1536092734}'

>>> ujson.dumps({'decimal': decimal.Decimal('3.14')})
>>> '{"decimal":3.14}'

如上这些,如果使用标准库里的json,就会出错。更有趣的是,标准库json能把不该编码的也编码了:

>>> json.dumps({'float': float('Nan')})
>>> '{"float": NaN}'

而ujson是会报错的,之所以是不该编码,就是因为很多其他语言包括js,都是不支持NaN这种东东的。

发表于2018-03-14 19:25   修改于2018-09-05 00:28   评论:0   阅读:218  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo