者 | 猪哥
责编 | maozz
JSON的诞生原因是因为XML整合到HTML中各个浏览器实现的细节不尽相同,所以道格拉斯·克罗克福特(Douglas Crockford) 和 奇普·莫宁斯达(Chip Morningstar)一起从JS的数据类型中提取了一个子集,作为新的数据交换格式,因为主流的浏览器使用了通用的JavaScript引擎组件,所以在解析这种新数据格式时就不存在兼容性问题,于是他们将这种数据格式命名为 “JavaScript Object Notation”,缩写为 JSON,由此JSON便诞生了!
今天我们来学习一下JSON的结构形式、数据类型、使用场景以及注意事项吧!
JSON格式
上面我们知道JSON是从JavaScript的数据类型中提取出来的子集,那JSON有几种结构形式呢?又有哪些数据类型呢?他们又分别对应着JavaScript中的哪些数据类型呢?
JSON的2种结构形式,键值对形式和数组形式。
举了一个JSON的实例,就是键值对形式的,如下:
{
"person": {
"name": "pig",
"age": "18",
"sex": "man",
"hometown": {
"province": "江西省",
"city": "抚州市",
"county": "崇仁县"
}
}
}
这种结构的JSON数据规则是:一个无序的“‘名称/值’对”集合。一个对象以 {左括号 开始, }右括号 结束。每个“名称”后跟一个 :冒号 ;“‘名称/值’ 对”之间使用 ,逗号 分隔。
因为大多数的时候大家用的JSON可能都是上面那种key-value形式,所以很多人在讲解JSON的时候总是会忽略数组形式,这一点是需要注意的。
那JSON的数组形式是怎么样的呢?举一个实例吧!
["pig", 18, "man", "江西省抚州市崇仁县"]
数组形式的JSON数据就是值(value)的有序集合。一个数组以 [左中括号 开始, ]右中括号 结束。值之间使用 ,逗号 分隔。
JOSN的6种数据类型
上面两种JSON形式内部都是包含value的,那JSON的value到底有哪些类型,而且上期我们说JSON其实就是从Js数据格式中提取了一个子集,那具体有哪几种数据类型呢?
string:字符串,必须要用双引号引起来。
number:数值,与JavaScript的number一致,整数(不使用小数点或指数计数法)最多为 15 位,小数的最大位数是 17。
object:JavaScript的对象形式,{ key:value }表示方式,可嵌套。
array:数组,JavaScript的Array表示方式[ value ],可嵌套。
true/false:布尔类型,JavaScript的boolean类型。
:空值,JavaScript的。
以上数据形式图片来源JSON官方文档:http://www.json.org/json-zh.html
JSON使用场景
介绍完JSON的数据格式,那我们来看看JSON在企业中使用的比较多的场景。
接口返回数据和序列化。JSON用的最多的地方莫过于Web了,现在的数据接口基本上都是返回的JSON,具体细化的场景有:
Ajxa异步访问数据
RPC远程调用
前后端分离后端返回的数据
开放API,如百度、高德等一些开放接口
企业间合作接口
这种API接口一般都会提供一个接口文档,说明接口的入参、出参等,
一般的接口返回数据都会封装成JSON格式,比如类似下面这种
{
"code": 1,
"msg": "success",
"data": {
"name": "pig",
"age": "18",
"sex": "man",
"hometown": {
"province": "江西省",
"city": "抚州市",
"county": "崇仁县"
}
}
}
程序在运行时所有的变量都是保存在内存当中的,如果出现程序重启或者机器宕机的情况,那这些数据就丢失了。一般情况运行时变量并不是那么重要丢了就丢了,但有些内存中的数据是需要保存起来供下次程序或者其他程序使用。
保存内存中的数据要么保存在数据库,要么保存直接到文件中,而将内存中的数据变成可保存或可传输的数据的过程叫做序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
正常的序列化是将编程语言中的对象直接转成可保存或可传输的,这样会保存对象的类型信息,而JSON序列化则不会保留对象类型!
为了让大家更直观的感受区别,猪哥用代码做一个测试,大家一目了然
Python对象直接序列化会保存class信息,下次使用loads加载到内存时直接变成Python对象。
JSON对象序列化只保存属性数据,不保留class信息,下次使用loads加载到内存可以直接转成dict对象,当然也可以转为Person对象,但是需要写辅助方法。
对于JSON序列化不能保存class信息的特点,那JSON序列化还有什么用?答案是当然有用,对于不同编程语言序列化读取有用,比如:我用Python爬取数据然后转成对象,现在我需要将它序列化磁盘,然后使用Java语言读取这份数据,这个时候由于跨语言数据类型不同,所以就需要用到JSON序列化。
存在即合理,两种序列化可根据需求自行选择!
最后就是生成Token和配置文件
首先声明Token的形式多种多样,有JSON、字符串、数字等等,只要能满足需求即可,没有规定用哪种形式。
JSON格式的Token最有代表性的莫过于JWT(JSON Web Tokens)。
随着技术的发展,分布式web应用的普及,通过Session管理用户登录状态成本越来越高,因此慢慢发展成为Token的方式做登录身份校验,然后通过Token去取Redis中的缓存的用户信息,随着之后JWT的出现,校验方式更加简单便捷化,无需通过Redis缓存,而是直接根据Token取出保存的用户信息,以及对Token可用性校验,单点登录更为简单。
使用JWT做过app的登录系统,大概的流程就是:
用户输入用户名密码
app请求登录中心验证用户名密码
如果验证通过则生成一个Token,其中Token中包含:
用户的uid、Token过期时间、过期延期时间等,然后返回给app
app获得Token,保存在cookie中,下次请求其他服务则带上
其他服务获取到Token之后调用登录中心接口验证
验证通过则响应
JWT登录认证有哪些优势:
性能好:服务器不需要保存大量的session
单点登录(登录一个应用,同一个企业的其他应用都可以访问):使用JWT做一个登录中心基本搞定,很容易实现。
兼容性好:支持移动设备,支持跨程序调用,Cookie 是不允许垮域访问的,而 Token 则不存在这个问题。
安全性好:因为有签名,所以JWT可以防止被篡改。更多JWT相关知识自行在网上学习,本文不过多介绍!
说实话JSON作为配置文件使用场景并不多,最具代表性的就是npm的package.json包管理配置文件了,下面就是一个npm的package.json配置文件内容。
{
"name": "server", //项目名称
"version": "0.0.0",
"private": true,
"main": "server.js", //项目入口地址,即执行npm后会执行的项目
"scripts": {
"start": "node ./bin/www" ///scripts指定了运行脚本命令的npm命令行缩写
},
"dependencies": {
"cookie-parser": "~1.4.3", //指定项目开发所需的模块
"debug": "~2.6.9",
"express": "~4.16.0",
"http-errors": "~1.6.2",
"jade": "~1.11.0",
"morgan": "~1.9.0"
}
}
但其实JSON并不合适做配置文件,因为它不能写注释、作为配置文件的可读性差等原因。
配置文件的格式有很多种如:toml、yaml、xml、ini等,目前很多地方开始使用yaml作为配置文件格式。
JSON在Python中的使用
最后我们来看看Python中操作JSON的常用方法有哪些,在Python中操作JSON时需要引入json标准库。
import json
类型转换
Python类型转JSON:json.dump
# 1、Python的dict类型转JSON
person_dict={'name': 'pig', 'age': 18, 'sex': 'man', 'hometown': '江西抚州'}
# indent参数为缩进空格数
person_dict_json=json.dumps(person_dict, indent=4)
print(person_dict_json, '\n')
# 2、Python的列表类型转JSON
person_list=['pig', 18, 'man', '江西抚州']
person_list_json=json.dumps(person_list)
print(person_list_json, '\n')
# 3、Python的对象类型转JSON
person_obj=Person('pig', 18, 'man', '江西抚州')
# 中间的匿名函数是获得对象所有属性的字典形式
person_obj_json=json.dumps(person_obj, default=lambda obj: obj.__dict__, indent=4)
print(person_obj_json, '\n')
执行结果:
JSON转Python类型:json.loads
# 4、JSON转Python的dict类型
person_json='{ "name": "pig","age": 18, "sex": "man", "hometown": "江西抚州"}'
person_json_dict=json.loads(person_json)
print(type(person_json_dict), '\n')
# 5、JSON转Python的列表类型
person_json2='["pig", 18, "man", "江西抚州"]'
person_json_list=json.loads(person_json2)
print(type(person_json_list), '\n')
# 6、JSON转Python的自定义对象类型
person_json='{ "name": "pig","age": 18, "sex": "man", "hometown": "江西抚州"}'
# object_hook参数是将dict对象转成自定义对象
person_json_obj=json.loads(person_json, object_hook=lambda d: Person(d['name'], d['age'], d['sex'], d['hometown']))
print(type(person_json_obj), '\n')
执行结果如下:
对应的数据类型
上面我们演示了Python类型与JSON的相互转换,最开始的时候我们讲过JSON有6种数据类型,那这6种数据类型分别对应Python中的哪些数据类型呢?
需要注意的点
JSON的键名和字符串都必须使用双引号引起来,而Python中单引号也可以表示为字符串,所以这是个比较容易犯的错误!
Python类型与JSON相互转换的时候到底是用load/dump还是用loads\dumps?
他们之间有什么区别?
什么时候该加s什么时候不该加s?
这个我们可以通过查看源码找到答案:
不加s的方法入参多了一个fp表示filepath,最后多了一个写入文件的操作。
所以我们在记忆的时候可以这样记忆:
加s表示转成字符串(str),不加s表示转成文件。
Python自定义对象与JSON相互转换的时候需要辅助方法来指明属性与键名的对应关系,如果不指定一个方法则会抛出异常!
相信有些看的仔细的同学会好奇上面使用json.dumps方法将Python类型转JSON的时候,如果出现中文,则会出现:
\u6c5f\u897f\u629a\u5dde
这种东西,这是为什么呢?
原因是:Python 3中的json在做dumps操作时,会将中文转换成unicode编码,并以16进制方式存储,而并不是UTF-8格式!
总结
今天我们学习了JSON的2种形式,切记JSON还有[...]这种形式的。
学习了JSON的6种数据类型他们分别对于Python中的哪些类型。
了解了JSON的一些使用场景以及实际的例子。
还学习了在Python中如何使用JSON以及需要注意的事项。
一个JSON知识点却分两篇长文(近万字)来讲,其重要性不言而喻。因为不管你是做爬虫、还是做数据分析、web、甚至前端、测试、运维,JSON都是你必须要掌握的一个知识点
本文为作者投稿,版权归作者个人所有。
SON(JavaScript Object Notation)是一种轻量级的数据交换格式,JSON格式的数据,主要是为了跨平台交流数据用的。
但JSON和JavaScript确实存在渊源,可以说这种数据格式是从JavaScript对象中演变出来的,它是JavaScript的一个子集。JSON本身的意思就是JavaScript对象表示法(JavaScript Object Notation),它用严格的JavaScript对象表示法来表示结构化的数据。
它是一种严格的js对象的格式,JSON的属性名必须有双引号,如果值是字符串,也必须是双引号;
JSON只是一种数据格式(或者叫数据形式),数据格式其实就是一种规范,格式、形式、规范是不能用来存诸数据的。我们不能把以下的对象叫JSON,比如:
<script>
var obj2={};//这只是JS对象
var obj3={width:100,height:200};/*这跟JSON就更不沾边了,只是JS的 对象 */
var obj4={'width':100,'height':200};/*这跟JSON就更不沾边了,只是JS的对象 */
var obj5={"width":100,"height":200,"name":"rose"}; /*我们可以把这个称做:JSON格式的JavaScript对象 */
var str1='{"width":100,"height":200,"name":"rose"}';/*我们可以把这个称做:JSON格式的字符串 */
var a=[
{"width":100,"height":200,"name":"rose"},
{"width":100,"height":200,"name":"rose"},
{"width":100,"height":200,"name":"rose"},
];
/*这个叫JSON格式的数组,是JSON的稍复杂一点的形式 */
var str2='['+
'{"width":100,"height":200,"name":"rose"},'+
'{"width":100,"height":200,"name":"rose"},'+
'{"width":100,"height":200,"name":"rose"},'+
']' ;
/* 这个叫稍复杂一点的JSON格式的字符串 */
</script>
在互联网上,最流行的两大传输数据的标准就是json和XML了,关于谁是最好的,一直以来都是人们争论的话题,其实各有各的缺点和优点;
1.定义介绍
(1).XML定义
扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML使用DTD(document type definition)文档类型定义来组织数据;格式统一,跨平台和语言,早已成为业界公认的标准。
XML是标准通用标记语言 (SGML) 的子集,非常适合 Web 传输。XML 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。
(2).JSON定义
JSON(JavaScript Object Notation)一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。可在不同平台之间进行数据交换。JSON采用兼容性很高的、完全独立于语言文本格式,同时也具备类似于C语言的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)体系的行为。这些特性使JSON成为理想的数据交换语言。
JSON基于JavaScript Programming Language , Standard ECMA-262 3rd Edition - December 1999 的一个子集。
2.XML和JSON优缺点
(1).XML的优缺点
<1>.XML的优点
A.格式统一,符合标准;
B.容易与其他系统进行远程交互,数据共享比较方便。
<2>.XML的缺点
A.XML文件庞大,文件格式复杂,传输占带宽;
B.服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;
C.客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;
D.服务器端和客户端解析XML花费较多的资源和时间。
(2).JSON的优缺点
<1>.JSON的优点:
A.数据格式比较简单,易于读写,格式都是压缩的,占用带宽小;
B.易于解析,客户端JavaScript可以简单的通过eval()进行JSON数据的读取;
C.支持多种语言,包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等服务器端语言,便于服务器端的解析;
D.在PHP世界,已经有PHP-JSON和JSON-PHP出现了,偏于PHP序列化后的程序直接调用,PHP服务器端的对象、数组等能直接生成JSON格式,便于客户端的访问提取;
E.因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。
<2>.JSON的缺点
A.没有XML格式这么推广的深入人心和喜用广泛,没有XML那么通用性;
B.JSON格式目前在Web Service中推广还属于初级阶段。
3.XML和JSON的优缺点对比
(1).可读性方面。
JSON和XML的数据可读性基本相同,JSON和XML的可读性可谓不相上下,一边是建议的语法,一边是规范的标签形式,XML可读性较好些。
(2).可扩展性方面。
XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,JSON不能的。
(3).编码难度方面。
XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的编码明显比XML容易许多,即使不借助工具也能写出JSON的代码,可是要写好XML就不太容易了。
(4).解码难度方面。
XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析难度几乎为0。这一点XML输的真是没话说。
(5).流行度方面。
XML已经被业界广泛的使用,而JSON才刚刚开始,但是在Ajax这个特定的领域,未来的发展一定是XML让位于JSON。到时Ajax应该变成Ajaj(Asynchronous Javascript and JSON)了。
(6).解析手段方面。
JSON和XML同样拥有丰富的解析手段。
(7).数据体积方面。
JSON相对于XML来讲,数据的体积小,传递的速度更快些。
(8).数据交互方面。
JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。
(9).数据描述方面。
JSON对数据的描述性比XML较差。
(10).传输速度方面。
JSON的速度要远远快于XML。
4.XML与JSON数据格式比较
(1).关于轻量级和重量级
轻量级和重量级是相对来说的,那么XML相对于JSON的重量级体现在哪呢?应该体现在解析上,XML目前设计了两种解析方式:DOM和 SAX。
<1>.DOM
DOM是把一个数据交换格式XML看成一个DOM对象,需要把XML文件整个读入内存,这一点上JSON和XML的原理是一样的,但是XML要考虑父节点和子节点,这一点上JSON的解析难度要小很多,因为JSON构建于两种结构:key/value,键值对的集合;值的有序集合,可理解为数组;
<2>.SAX
SAX不需要整个读入文档就可以对解析出的内容进行处理,是一种逐步解析的方法。程序也可以随时终止解析。这样,一个大的文档就可以逐步的、一点一点的展现出来,所以SAX适合于大规模的解析。这一点,JSON目前是做不到得。
所以,JSON和XML的轻/重量级的区别在于:
JSON只提供整体解析方案,而这种方法只在解析较少的数据时才能起到良好的效果;
XML提供了对大规模数据的逐步解析方案,这种方案很适合于对大量数据的处理。
(2).关于数据格式编码及解析难度
<1>.在编码方面。
虽然XML和JSON都有各自的编码工具,但是JSON的编码要比XML简单,即使不借助工具,也可以写出JSON代码,但要写出好的XML代码就有点困难;与XML一样,JSON也是基于文本的,且它们都使用Unicode编码,且其与数据交换格式XML一样具有可读性。
主观上来看,JSON更为清晰且冗余更少些。JSON网站提供了对JSON语法的严格描述,只是描述较简短。从总体来看,XML比较适合于标记文档,而JSON却更适于进行数据交换处理。
<2>.在解析方面。
在普通的web应用领域,开发者经常为XML的解析伤脑筋,无论是服务器端生成或处理XML,还是客户端用 JavaScript 解析XML,都常常导致复杂的代码,极低的开发效率。
实际上,对于大多数Web应用来说,他们根本不需要复杂的XML来传输数据,XML宣称的扩展性在此就很少具有优势,许多Ajax应用甚至直接返回HTML片段来构建动态Web页面。和返回XML并解析它相比,返回HTML片段大大降低了系统的复杂性,但同时缺少了一定的灵活性。同XML或 HTML片段相比,数据交换格式JSON 提供了更好的简单性和灵活性。在Web Serivice应用中,至少就目前来说XML仍有不可动摇的地位。
*请认真填写需求信息,我们会在24小时内与您取得联系。