《JSON必知必会》- 学习笔记

JSON(读音:Jei森) - JavaScipt Object Notation

JSON概述

什么是JSON: JSON是一种数据交换格式 (实现在不同系统之间的数据交换)

数据交换格式(Data exchange format)是一种在不同平台之间传递数据的文本格式。

可移植性(以一种双方都兼容的方式在平台之间传递信息)在平台和系统之间传输信息的兼容性,是一种数据交换格式的重要指标

In JSON, keys must be strings, written with double quotes. eg:

JSON语法

JSON基于JS对象字面量(字面量是对数据值的具体表示。其字面意思与想要表达的意思是完全一致的 -> 字面量只是表达字面意思而非任何隐喻的内容)

实例: 描述一个学生信息

{
	"id" : 1,
	"name" : "Wangzhaung2",
	"age" : 21,
	"school" : "a Nuist student",
	"isRich" : false
}

一个对象的字面量直接以一种可以直接可见的方式展现出来。 对象的特征或属性所采用的表示方法: 名称(Key) - 值(Value)对

JSON是基于JavaScript对象字面量的而数据交换格式的核心是: 数据-Data

Key-Type: 字符串类型
Value-Type: 数字、布尔值、数组、对象、null等其他数据类型

{} -> 读取对象[] -> 读取数组 : -> 名称-值对中分割Key和Value , -> 指分割对象中的名称-值对或分割数组中的值

★★★ JSON的双引号 在JSON之中无论如何都使用双引号

Eg: ❌错误1:没有将Key加上双引号

{
      title : "This is my title.",   // ---> 改正 "title" : "This is my title." ✔
      body : "This is the body."    // ---> 改正 "body" : "This is the body." ✔
}

===》未在"title"和"body"的两边加上双引号。 没有在名称上加上双引号时该值不是JSON而是JS对象

Eg: ❌错误2:在JSON中只会出现双引号【""】而不会出现单引号【''】(在JS中允许一个对象使用单双引号)

{
      'title' : 'This is my title.', // ---> 改正 "title" : "This is my title." ✔
      'body' : 'This is the body.' // ---> 改正 "body" : "This is the body." ✔
}
  • JSON文件: JSON作为数据转换格式可以作为独立的文件存在文件系统中,扩展名*.json
  • JSON媒体类型: JSON的MIME类型是application/json

小结

  • 字面量: 字面意思与实际表达意思一致,直接表述某一对象的直接特征。

  • 键值对:拥有名称和对应的值的属性或特征(Key-Value)

  • JSON中的key ---> 必须是被双引号包裹,eg: {"key":xx}

  • JSON中的value ---> 可以是:字符串、数字、布尔值、null、对象、数组

  • JSON的 key:value由 {}包裹

  • JSON文件的扩展名: *.json 多媒体类型: application/json

  • JSON中的布尔类型只存在:true 或 false且所有字母必须是小写

JSON Schema

JSON Schema使用JSON来书写,仅需要几步就可以掌握。需要在JSON第一个名称-值对中,声明其为一个schema文件
在第一 key-value声明当前是schema文件

{
      "$schema" : "http://json-schema.org/draft-04/schema#"
}

在第二 key-value是JSON Schema的文件标题

{
      "$schema" : "http://json-schema.org/draf-04/schema#",
      "title" : cat
}

在第三 key-value定义JSON要包含的属性

{
      "$schema" : "http://json-schema.org/draft-04/schema#",
      "title" : cat,
      "properties" : {
                        "name":{"type":"string"}, 
                        "age":{"type":"number"},
                        "description":"Your cat's age in years."
}

定义必填字段

{
      "$schema" : "http://json-schema.org/draft-04/schema#",
      "title" : cat,
      "properties" : {
                        "name":{"type":"string"}, 
                        "age":{"type":"number", "description":"Your cat's age in years."},
                        "required":["name","age"]
}

在将"required"字段加入JSON Schema后,合法的JSOn包含了在Schema中定义的"name"、"age"两个个字段包含可选字段description

JSON Schema数据交换中的一种虚拟的合同“contract”

JSON的安全问题

JSON本身只提供数据交换的方式并不会造成安全问题(是一种数据文件、数据流)但在Web中使用JSOn时最常见的两个问题: 跨站请求伪造跨站脚本攻击

跨站请求伪造 - CSRF(Cross-site request forgery)

跨站请求伪造即CSRF(Cross-site request forgery)是一种利用站点对用户浏览器信任而发起攻击的方式

将数组放在对象之中,使其成为非法的JavaScript,这样就不会被<script>标签加载

{
      "info" : [
            {"user" : "bobbarker"},
            {"phone" : "xxx-xxx-xxx"}
      ]
}

服务器只提供POST请求获取数据,禁止使用GET请求,此时将无法使用黑客的URL中伪造连接。GET和POST是HTTP提供的用于与服务器交换数据的安陵中方法
GET 用于请求数据得到响应。
POST 用于提交数据得到响应。
如果服务器端允许GET请求,就可以直接通过浏览器或<script>标签连接到该服务器资源,但POST不可以被直接链接到。(无法使用<script>标签黑客将受到资源共享的限制,无法利用银行对客户端的信任进行任何攻击的行为)

是否使用GET方法请求页面或资源: 该页面是否需要通过URL或<script>标签来加载?如果不需要通过URL或<script>标签获取数据则禁用GET方法。
不在JSON中使用顶级数组,不要贪图使用GET代替POST的遍历

跨站脚本攻击(cross-site scripting, XSS)

跨站脚本攻击是注入攻击的一种。在JSON中常见的安全漏洞是发生在JS从Server中获取一段JSON字符串并将其转化为对象时。

JSON本质是文本,对代表对象的文本进行操作,要将其加载到内存之中,这样才能被操作、观察并在程序逻辑中使用。
在JS中可以使用eval()函数来实现对数据的操作

var jsonString = '{"animal" : "cat"}';
var myObject = eval("(" + jsonString + ")");
alert(myObject.animal);

JSON从别的服务器上获取则己方无权控制第三方服务器,如果服务器本身或发来的JSON数据被劫持则可能会运行恶意代码

eval()函数的问题: 将传入的字符串无差别的编译执行。
Eg: 使用JS代码来替换原来的JSON字符串。当代码执行时,eval()函数会执行alert()函数并弹出"this is bad"

var jsonString = "alert('this is bad')";
var myObject = eval("(" + jsonString + ")");
alert(myObject.animal);

JSON.parse()函数用来处理这一漏洞,只会解析JSON但不会执行任何脚本。

// 使用JSON.parse() 代替 eval()
var jsonString = '{"animal" : "cat"}';
var myObject = JSON.parse(jsonString);
alert(myObject.animal);

安全漏洞: 决策上的失误

Eg: 规矩JSON

{
      "message" : "hello,world"
}

Eg: 不规矩JSON

{
      "message" : "<div onmouseover=\"alert('gotcha!')\">hover here.</div>"
}

如何阻止此类情况,可以在消息中添加限制要求将消息中的HTML进行转码 这样 <div>标签将被转换为 &lt;div&gt;然后插入页面中
★★★ 注入攻击之所以会成功,在于网站在架构过程中忽视了一个问题: 允许在JSON中使用或直接将值插入页面中的一些决策。

抵御注入攻击的关键是: 找出可能的注入点,并添加一些额外的步骤来加以防范

小结

  1. CSRF - 跨站请求伪造: 利用站点对用户浏览器的信息进行的攻击。

  2. 顶层JSON数组 - 存在于JSON名称-值对之外的位于文档最顶层的JSON数组。(禁止使用)

  3. 注入攻击: 依赖于将数据注入到Web App以方便而恶意数据执行或编译的攻击。

  4. JSON跨站脚本攻击: 使用第三方代码更换为恶意脚本对站点进行一种注入攻击。

  5. JSON安全问题:

    • 不要使用顶级数组。顶级数组是合法的JS脚本,可以用<script>标签连接并使用
    • 对不想公开的资源,仅允许使用HTTP POST方法请求,而不是GET方法。GET方法可以通过URL来请求,甚至可以放在<script>标签之中
    • 使用JSON.parse()来代替eval()eval()函数传入的字符串编译并执行会让代码易受到攻击。 ✔★仅使用JSON.parse()来解析JSON数据
  • 安全漏洞通常是由于开发人员没有考虑到 "黑客如何利用这一点“ 这一问题造成的(想他人所想)

JavaScript中的XMLHttpRequest与Web API

JS的XMLHttpRequest负责在客户端发起请求
Web API负责在服务端返回响应
客户端 ==》 用餐的人,服务端 ==》厨房

互联网浏览器发送的是对某项资源的请求.

JS中的XMLHttpRequest对象

var myXmlHttpRequest = new XmlHttpRequest(); // 创建XmlHttpRequest对象
XMLHttpRequest中以下可用的函数:

  1. open(method, url, async(可选), user(可选), password(可选)

  2. send()

  3. onreadystatechange // 可以在代码中赋值为一个函数

  4. readyState // 返回一个0~4的值,用来表示状态码

  5. status // 返回HTTP状态码(eg: 200表示请求成功)

  • responseText // 当请求成功时,该属性会包含作为文本的响应体(eg: 请求的JSON)

属性的值可以是一个函数。JS中的函数本身也是一个对象。对象这一类数据可以被赋值给一个变量(属性)、修改和传递。

===》 一个新的XMLHttpRequest对象

var myXMLHttpRequest = new XMLHttpRequest();
var url = "http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139";

myXMLHttpRequest.onreadystatechange = function(){
      if(myXMLHttpRequest.readyState === 4 && myXMLHttpRequest.status === 200){
            var myObject = JSON.parse(myXMLHttpRequest.responseText);
            var myJSON = JSON.stringify(myObject);
      }
}
myXMLHttpRequest.open("GET", url, true);
myXMLHttpRequest.send();

将一个对象转成JSON文本,或是将JSON文本转成对象时 ===》 序列化和反序列化。
序列化: 将对象转成JSON文本的过程
反序列化: 将文本转换成对象的过程

  • 反序列化: 将文本转换成对象
    var myObject = JSON.parse(myXMLHttpRequest.responseText);

  • 序列化:将对象转换成文本
    var myJSON = JSON.stringify(myObject);

就绪状态0-4的含义

DESC URL
0表示未发送 表示open()函数还没有执行
1表示已发送 表示open()函数已执行,但send()函数还没有执行
2表示接收到头部 表示send()函数已执行且头部和状态码还没有获取
3表示解析中 表示头部已经收到,但响应体正在解析中
4表示完成 表示请求完成,包括响应头和响应体的内容都已经接收到

小结

  1. Web API 通过HTTP与服务进行交互的一系列指令与标准

  2. XMLHttpRequest 一种JS对象,无需刷新页面即可从要给URL中获取数据,常用于AJAX 编程

  3. HTTP 作为万维网使用的交换数据的基本协议

  4. 序列化: 将对象转换为文本 反序列化: 将文本转换成对象

  5. 同源策略: 出于安全的考虑,浏览器仅会请求同一个域的脚本

  6. 跨域资源共享(CORS): 通过设置响应头,使得跨域请求资源(eg: JSON doc)可以成功

  7. JSON-P:使用<script>标签, 绕过同源策略的限制,以从不同域名的服务器上请求JSON

  8. 网站为人服务,Web API为代码服务均使用HTTP协议

posted @ 2020-11-25 10:48  Felix_Openmind  阅读(149)  评论(0编辑  收藏  举报