《JSON必知必会》读书笔记
2021-07-28 08:52:43 0 举报
AI智能生成
越来越多的IT 从业者需要学习或了解JSON。本书即针对这一现状,围绕JSON 这一主题的核心展开讲解,首先介绍JSON 语法、语法验证、数据类型、模式验证、安全问题,再讲解JSON 作为数据交换格式所扮演的种种角色,还涉及jQuery、AngularJS 以及CouchDB 等技术的进阶介绍,并给出了大量代码示例,是一本让读者快速透彻地了解JSON 的指南。
作者其他创作
大纲/内容
0.图书介绍
越来越多的IT 从业者需要学习或了解JSON。本书即针对这一现状,围绕JSON 这一主题的核心展开讲解,首先介绍JSON 语法、语法验证、数据类型、模式验证、安全问题,再讲解JSON 作为数据交换格式所扮演的种种角色,还涉及jQuery、AngularJS 以及CouchDB 等技术的进阶介绍,并给出了大量代码示例,是一本让读者快速透彻地了解JSON 的指南。
1.什么是JSON
是一种数据交换格式
如果每一个系统都必须有一个专门针对其他所有系统的数据组织形式的翻译组件,那么它们之间的交流便要消耗许多时间和资源,这显然是不合理的。所以,这些系统间也需要一种单一的数据格式,以及单一的翻译组件。
其他格式
XML
CSV
独立于编程语言
可移植性,或者说在平台和系统间传输信息的兼容性,是一种数据交换格式所追求的一个重要指标。
如果你以后用不到JavaScript,那也没有必要去学习它,因为数据交换格式是独立于语言的。你仍可以在你自己的系统中使用你自己的语言。
数据交换格式的核心是数据,所以JSON中并不会涉及JavaScipt对象字面量中的函数
JSON基于JavaScript对象字面量表示法(重点在于“表示法”)
编程语言中的literal(字面量)是一个名词。所谓字面量,是对数据值的具体表示。它的字面意思与其想要表达的意思是完全一致的
JSON表达数据的方式对通用的编程概念都很友好
JSON的全称是JavaScript Object Notlion(Javascript对象表示法)
2.JSON语法
名称-值对
在JSON中,名称一值对的值还可以是数字、布尔值、null、数组或对象。
JSON中使用冒号(:)来分隔名称和值。名称始终在左侧,值始终在右侧。
为了获得最大可移植性,应尽可能避免使用空格或特殊字符
当值是字符串时,必须使用双引号
而在JSON中,还有数字、布尔值、数组、对象、null等其他数据类型,这些都不应被双引号包裹。
{(左花括号)指“开始读取对象”
}(右花括号)指“结束读取对象”
[(左方括号)指“开始读取数组”
](右方括号)指“结束读取数组”
:(冒号)指“在名称-值对中分隔名称和值”
,(逗号)指“分隔对象中的名称一值对”或者“分隔数组中的值”;也可以认为是“一个新部分的开始”。
}(右花括号)指“结束读取对象”
[(左方括号)指“开始读取数组”
](右方括号)指“结束读取数组”
:(冒号)指“在名称-值对中分隔名称和值”
,(逗号)指“分隔对象中的名称一值对”或者“分隔数组中的值”;也可以认为是“一个新部分的开始”。
语法验证
有许多在线工具可以帮助你格式化和验证JSON。
JSON Formatter & Validator(https:/jsonformatter.curiousconcept.com/)
JSON Editor Online(htp:/www.isoneditoronline.ore)
JSONLint(htp:/jsonlintcom/)
媒体类型
JSON的MIME 类型是appLication/json。
互联网数字分配机构(Internet Assigned Numbers Authority,IANA)维护着一个包含全部媒体类型的列表(http://www.iana.org/assignments/media-types/media-types.xhtml)。
3.JSON的数据类型
原始数据
在不同的编程语言中,这类“一成不变”的数据类型常被叫作原始数据类型或内置类型。这意味着它们的定义和操作都是不能修改的。
复合数据类型对象的数据结构可以被解构为原始数据类型。即便是对那些不支持对象数据类型的语言来说,一旦这一数据结构被解构为那些原生的类型,就很好处理了。
复合数据
除了原始数据类型,大多数编程语言中还有许多其他的类型。它们常常被称为复合数据类型,因为它们是由原始数据类型融合而成的。
一个数组:枚举数据类型是编程语言中常见的复合数据类型之一。
另一种复合数据类型是对象数据类型。
在JSON中,数组里可以包含任何支持的数据类型。所以可以有字符串构成的数组、数字构成的数组、布尔值构成的数组、对象构成的数组,甚至是数组构成的数组。数组构成的数组也被称为多维数组。
原始数据类型:字符串、数字和布尔值。
JSON中的字符串可以由任何Unicode字符构成,字符串的两边必须被双引号包裹。
在JavaScript中,使用单引号或双引号没有任何区别。然而请记住,JSON不是javaScript对象字面量,它只是基于JavaScript对象字面量。而在JSON中,仅允许使用双引号来包裹字符串。
对于JSON的字符串来说,双引号也不是唯一一个需要转义的字符。因为反斜线用于转义字符,所以我们还需要转义反斜线
示例3-8:反斜线需要另一个反斜线来转义
{
"Location":"C:\\Progran Files"
}
除了双引号和反斜线,还需要转义以下字符:
\/(正斜线)
\b(退格符)
\f(换页符)
\t(制表符)
\n(换行符)
\r(回车符)
\u后面跟十六进制字符(如笑脸表情\u263A)
{
"Location":"C:\\Progran Files"
}
除了双引号和反斜线,还需要转义以下字符:
\/(正斜线)
\b(退格符)
\f(换页符)
\t(制表符)
\n(换行符)
\r(回车符)
\u后面跟十六进制字符(如笑脸表情\u263A)
JSON中的数字可以是整数、小数、负数或者指数。
Null类型
对于一无所有的东西,你可能觉得用0来描述比较合适。比如,我有0个手表。但事实是,0是一个数字。这意味着本质上是在计数。
在编程中,null就用来表示0、一无所有、不存在等意思,而不用数字来表示、由于手表颜色的值也是不能被定义的,所以使用nuLL来描述。
不要把nuLL和undefined混淆,尤其是在使用JavaScript时。undefined不是JSON中的数据类型,而在Javascript中,undefined是在尝试获取一些不存在的对象或变量时返回的结果。在JavaScript中,undefined 与那些声明的名称和值都不存在的对象或变量有关,而null则仅与对象或变量的值有关。null是一个表示“没有值”的值。在JSON中,null必须使用小写形式。
4.JSON schema
资源
如果你希望深入掌握JSON Schema,可以访问下面的链接,了解相关规范:
·JSON Schema 主页(http://json-schema.org/)
·JSON Schema 验证规范(http/json-schema.org/latest/json-schema-validation.
html)
还有一些在线验证工具,它们都与编程语言无关,也是进行JSON Schema验证的好帮手:
·JSON Schema Lint (http://jsonschemalint.com/draft4/)
·JSON Schema Validator(http://www.jsonschemavalidator.net)
·JSON Schema 主页(http://json-schema.org/)
·JSON Schema 验证规范(http/json-schema.org/latest/json-schema-validation.
html)
还有一些在线验证工具,它们都与编程语言无关,也是进行JSON Schema验证的好帮手:
·JSON Schema Lint (http://jsonschemalint.com/draft4/)
·JSON Schema Validator(http://www.jsonschemavalidator.net)
用途
它可以在数据被处理前回答下面的所有问题。
值的数据类型是否正确?
可以具体规定一个值是数字、字符串等类型。
是否包含所需要的数据?
可以具体规定哪些数据是需要的,哪些是不需要的。
值的形式是不是我需要的?
可以指定范围、最小值和最大值。
值的数据类型是否正确?
可以具体规定一个值是数字、字符串等类型。
是否包含所需要的数据?
可以具体规定哪些数据是需要的,哪些是不需要的。
值的形式是不是我需要的?
可以指定范围、最小值和最大值。
05.JSON安全问题
跨站请求伪造
跨站请求伪造,即CSRF(cross-site request forgery,读作sea-surf),是一种利用站点对用户浏览器信任而发起攻击的方式。CSRF漏洞已经存在了很长时间,远比JSON出现得早。
不在JSON中使用顶级数组,且不要贪图使用GET代替POST的便利,这样你就不会写出那些满是漏洞、让用户感到愤怒的代码。
银行应仅允许POST请求获取数据,禁止使用GET请求,这样黑客便无法使用他自己的URL中的链接了。GET和POST是HTTP提供的用于与服务器交换数据的两种方法。GET用于请求数据,得到响应。POST用于提交数据,得到响应。如果服务器端允许GET请求,就可以直接通过浏览器或<script>标签链接到它。但POST则不可以直接被链接到。一旦不能使用<script>标签,黑客就会受到资源共享策略的限制,从而无法通过利用银行对客户端的信任进行欺骗行为。
跨站脚本攻击
注入攻击包含许多种形式与格式。不过,它们都是利用系统本身的漏洞来实现的。CSRF攻击仅包括利用信任机制进行的攻击。注入攻击则主要通过向网站注入恶意代码来实现。
跨站脚本攻击(cross-site scriping,XSS)是注入攻击的一种。在使用JSON时常见的安全漏洞通常发生在JavaScript从服务器获取到一段JSON字符串并将其转化为JavaScript对象时。
在JavaScript中,可以使用eval()函数来进行这一操作。该函数获取一段字符串,并对其进行编译与执行。eval()函数的问题是,它会将传入的字符串无差别地编译执行。如果从第三方服务器中获取的JSON被替换为了恶意脚本,那么我的站点就会无辜地蒙冤,在访问者的浏览器中编译执行恶意代码。
随着JSON本身的不断发展,这一漏洞已得到公认。JSON.parse()函数就是用来处理这一问题的。该函数仅会解析JSON,并不会执行脚本。
客户端和服务端的关系
客户端就是发生在用户浏览器中的一切,而服务端则是发生在运行网站的服务器中的一切。当我们提起客户端代码时,通常指的是JavaScript、HTML或CSS。当我们提到服务端代码时,常常是指一些服务端语言,如ASP.NET、Ruby on Rails或Java。)
06.JavaScript中的XMLHttpRequest与Web APl
JavaScript中的XMLHttpRequest负责在客户端发起请求,而Web API负责在服务端返回响应。
JavaScript中的异步(后台)操作被称为AJAX。AJAX的全称是Asynchronous JavaScript and XML(异步的JavaScript和XML)。当在慕后请求JSON数据时,这从技术上讲可以被称为异步的JavaScript和JSON(AJAX)。然而,“AJAX”这个专有名词使用的时间已经很久了,所以很多时候,与其说它是一个首字母缩写,不如说是用来描写JavaScript中的任何一种异步操作。
请记住这句话:属性的值可以是一个函数。因为JavaScript中的函数也是一类对象。对象是一类数据,因此它可以被赋值给一个变量(属性)、修改和传递。在编程中,这种情况称为“函数是一等公民”。
序列化和反序列化
序列化是将对象转换成文本的过程,反序列化是将文本转换成对象的过程。
JavaScript中的JS0N.parse()进行反序列化操作。响应返回的JSON以文本的形式存储在responseText中。当它被JSON.parse()解析后,就不是JSON了,而是JavaScript对象。
由JSON一开始还不是对象,所以使用JSON.parse()进行反序列化是有必要的。请记住,JSON意思为JavaScript对象表示法。当它以JSON形式存在时,字面上代表的是以文本形式表示的一个对象。为了让JSON变为真正的对象,需要进行反序列化操作。
同源策略
出于安全考虑,浏览器对资源共享有一定的限制。同源策略就要求此类后台请求仅可以请求来自同一域名的资源。由于后台请求仅可在浏览器的开发者工具中看见,因此保护了普通用户的安全。
跨域资源共享
有些开发人员可以连续多年通过JavaScript的AJAX技术向公共API发送请求,而不会受到同源策略的影响。这是因为这些公共API的开发者在他们的服务器上实现了跨域资源共享(cross-origin resource sharing,CORS)。这些服务器会在响应头额外加上一些带有Access-Control-ALLow前缀的属性。
Access-Control-Allow-Credentials:true
Access-Control-Allow-Methods:GET,POST
Access-Control-Allow-Origin:*
JSON-P
JSON-P指带有padding的JSON。我在第5章提到过<script>标签不受同源策略的影响。JSON-P就是利用这一点来向不同域名的站点请求JSON的。
JSON-P并没有CORS那么理想,它只是一个备选方案(CORS是更好的方案,同时也是一种标准)。
JSON-P并没有CORS那么理想,它只是一个备选方案(CORS是更好的方案,同时也是一种标准)。
07.JSON与客户端框架
框架的价值
本质上讲,JavaScript框架可以节省时间,让我们更专注于功能的构建。
这种节约时间、专注重点的框架在计算机科学中也被称为抽象化工具。
抽象化工具就是用来帮助进行抽象化工作的。JavaScript框架中包含一些预定义的库,这些库已经解决了构建系统中的一些复杂问题,能让我们更方便地进行抽象化。虽说没有框架的话,我们可能造不出一艘飞船,但如果框架中包含一般可以发射到太空的飞船的话,就能造出来,这样我们就可以将精力投入到人类生命供给系统的构建中了。
JQuery
jQuery (htp:/jquery.com/)是一种允许开发者专注于操作DOM构建功能的抽象化工具。DOM为我们和HTML页面产生交互提供了便利。在这一模型中,底层的HTML可以被当作具有许多可以枚举、获取和操作的字节点的对象来处理。
不使用jQuery框架,单纯使用JavaScript来对DOM进行操作也是可行的。不过,开发人员需要定期对DOM执行一些操作,这通常通过写几行代码来实现。
在实现相同功能的前提下,更短的代码意味着更短的开发时间。为了节约更多的时间,jQuery还解决了跨浏览器兼容问题。
jquery帮你解决了大部分兼容问题,包括上面提到的JSON.parse()。jquery有自己的解析JSON函数。
jquery.parseJSON()函数所起的作用远不是一行代码能说明的。如果研究jQuery库中对应的源码,会发现它会先尝试使用原生的JSON.parse()函数。如果浏览器不支持,它会使用和eval()功能类似的new Function()。同时,它会对一些不合法的字符进行检测,如果发现其中有注入攻击的威胁,就会抛出错误。
jQuery框架通过缩减请求和解析JSON的时间来缩短开发时间,从而对JSON提供支持。其中包括了一种支持老式浏览器的解析JSON的方法。可以说,jQuery 支持与JSON交互。
AngularJS
AngularJS框架(http://angularjs.org/)是专注于创建单页应用的抽象化工具。与传统的多页方式不同,单页Web应用致力于为用户提供无缝交互的应用体验。
单页应用的目标就是在你的浏览器中实现同样的无缝浏览体验。这绝大部分是通过JavaScript以及我们的好朋友XMLHttpRequest实现的。当用户仍在当前页面时,幕后的代码已经完成对资源的请求,用户从一个资源跳跃到另一个资源的操作将不再需要通过URL或是指向URL的链接来进行。
单页Web应用是一类复杂的系统,而AngularJS并不会为其开发者构建一个单页应用。它所提供的,是一个基于模型-视图-控制器(MVC)架构概念的框架。
MVC
AngularJS实现的MVC概念如下所列。
模型Model
JavaScript对象即数据模型。
视图View
HTML(提供了与模型进行数据绑定的语法)。
控制器 Controller
使用AnguarIS语法来定义和操作与模型和视图间的交互的javaScript文件。
模型Model
JavaScript对象即数据模型。
视图View
HTML(提供了与模型进行数据绑定的语法)。
控制器 Controller
使用AnguarIS语法来定义和操作与模型和视图间的交互的javaScript文件。
AngularJS 试图将DOM操作和业务逻辑解耦。在AngularJS中,由于HTML位于视图层,所以应让它随时准备应对数据模型的变化。在AngularJS 的JavaScript按制器文件中,我们不去操作DOM,而是去操作数据模型。当你面对的是一个较为复杂的应用,比如开发一个允许用户对其信息执行创建、读取、更新、删除(CRUD)等操作的页面时,使用Angular会简化开发过程。
08.JSON与NOSQL
NOSQL
至于NOSQL,顾名思义,它不是一种关系型数据库。我们不能使用SQL从关联在一起的数据库表格的行和列中获取数据。不过,NoSQL这个名称并不能告诉我们它是什么。它只是表明“我找到了一种存储非关系型数据的替代方法”。
NoSQL数据库的一个例子是键值对存储
目前有20多种不同的文档存储数据库。它们有的使用XML文档,有的使用JSON文档
CouchDB
CouchDB(http:/couchdb.apache.org/)是一种使用JSON文档存储数据的NoSQL数据库。
由于CouchDB使用文档来存储数据,因此当我从数据库中查询一个账户时,得到的直接就是一个结构化的文档。
CouchDB使用基于HTTP的API
09.服务端的JSON
在Web客户端,我们通过HTTP向服务端发送资源请求。服务端会响应份文档,如HTML或JSON。当文档是JSON时,必须要用服务端代码来生成它。
JavaScript并不是唯一一个可以通过HTTP请求获取JSON资源的语言。服务端的Web框架也可以发起HTTP请求。此外通过服务端技术来请求JSON时,服务端扮演的其实是客户端的角色。
大部分服务端Web框架以及脚本语言都较好地支持JSON。就算没有内置序列化、反序列化JSON的功能,也会有库或扩展来支持它。
ASP.NET
ASP.NET是由微软开发的服务端Web框架。最开始时,该框架仅支持使用Web Forms—一种GUI状态驱动模型。不过现在,它通过扩展允许开发人员使用一些不同的编程模型,如ASP.NET MVC(一种模型-视图-控制器架构)和ASP.NET Web API(一种为Web服务构建HTTPWebAPI的架构)。
ASP.NET使用公共语言运行库(common language runtime,CLR),它允许开发人员使用任何受CLR支持的语言来编写代码,如C#、F#、Visual Basic .NET(VB.NET),等等。
在ASP.NET中解析JSON不像在Java Script中那么简单。若要解析JSON,需要使用第三方ASP.NET库,并将它带入工程中。
PHP
PHP对JSON的序列化和反序列化操作也有内置的支持。这类操作在PHP中称为JSON的编码与解码。对某样东西进行编码的意思是将它转为一种编码格式(即不可读的形式)。解码的意思则是将它转为一种可读的格式。对于PHP来说,JSON是一种编码格式。因此,序列化JSON时应调用json_encode函数,反序列化JSON时应调用json_decode函数。
Ruby on Rails
Raby on Rails是一个服务端的Web应用框架。它使用Ruby的语言编写且基于模型一视图-控制器(MVC)架构。
Ruby中的gem是一个用来安装程序或库的包。为在Ruby on Rails中对JSON进行序列化和反序列化操作,我们需要JSON ruby gem。一旦装好了JSON ruby gem,解析JSON就变得很简单了,只需执行JSON.parse()。
Node.js
Nodejs是服务端的JavaScript(脱离了浏览器),它基于谷歌的开源JavaScript引擎V8。有了Node.js,就可以使用JavaScript编写服务端应用。
在Node.js中不再使用XMLHttpRequest对象,因为该对象是仅在互联网浏览器中使用的JavaScript对象。在Node.js中,通过更简单的get()函数来请求JSON(以及其他类型的资源)。
Java
Java是一种面向对象的编程语言。它可以以Java小应用的形式运行在Web浏览器中,也可以通过Java运行环境(Java runtime environment,JRE)单独在机器上运行。
Java中的许多库都提供了对JSON的支持。可以使用下面的库来通过URL获取JSON,并将其序列化为Java对象。
·Apache Commons IO
·JSON in Java
0 条评论
下一页