Ajax与JSON

JSON

JSON是一种数据格式,而不是一种编程语言。JSON并不从属于JavaScript,并不是只有JavaScript才可以用JSON,但JSON在JavaScript中读写结构化数据的更好的方式。JSON作为一个轻量级的数据格式,可以简化表示复杂数据结构的工作量。

语法

JSON使用JavaScript语法的子集表示对象、数组、字符串、数值、布尔值和null,但不能表示特殊值undefined。JSON字符串必须使用双引号,而不能使用单引号。JSON的书写格式为:名称/值对,键值对之间用“,”分开。名称需要使用双引号。数组则使用“[]”包含子元素。实例如下:

{ "name":["liming","papa"], "qita":"不能为undefined。可以为字符串、数值、null或布尔值", "children":[{ "name":"laoda", "qita":null },{ "name":"laoer", "qita":true }] }

解析与序列化

JSON字符串与原生JavaScript值的主要区别在于名称,JSON名称需要使用双引号,而JavaScript的属性则不需要。还有JavaScript支持undefined,而JSON不支持。ECMAScript5对解析JSON的行为进行规范,定义了全局对象JSON,JSON对象有两个方法:stringify()和parse(),分别将JavaScript对象序列化为JSON字符串和将JSON字符串解析为JavaScript值。
对于JSON.stringify()方法,除了第一个为对象外,还可以接收两个参数:过滤器(可以为数组或函数)和是否保留缩进。如果需要将对象的名字也加入JSON字符串,可以在对象中使用toJSON():functiong(){……}方法。
JSON.parse()方法也可以接收另一个参数,该参数是一个函数,将在每个键值对上调用。

Ajax

Ajax技术的核心是XMLHttpRequest对象。XHR为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器取得更多消息,意味着用户点击后,可以不必刷新页面也能取得新数据。Ajax通信与数据格式无关。另外可以查看XMLHttpRequest标准

新建XMLHttpRequest对象

目前大多数浏览器都支持XMLHttpRequest(IE6之前的不支持),所以可以放心使用XMLHttpRequest。如下

使用open()启动请求

使用open启动一个请求,准备发送。最新的open()语法为:client.open(method, url [, async = true [, username = null [, password = null]]])。例子如下:

设置监听事件

一般我们将请求设为异步,可以通过onreadystatechange为xhr对象设置监听函数。接收到相应后,响应的数据会自动填充XHR对象的属性,相关的属性有:responseText、responseXML、status、statusText。

  • onreadystatechange:xhr的事件。readyState改变会触发此事件,所以通过监听此事件并检查状态确定请求所处状态
  • readyState:xhr的属性。0表示未初始化,即未调用open()方法。1表示启动,调用open()。2表示发送,调用send()。3表示接收,在接收数据。4表示完成,接收到全部响应数据。
  • responseText:xhr的属性。接收完响应后,该属性会被填充作为响应主体被返回的文本。
  • status:响应的HTTP状态。200表示成功、404表示未找到等。

设置XHR头、超时事件等

有时为了让后台可以解析我们发送的数据,我们需要设置请求头。如在发送json数据时,将Content-Type设为’application/json;charset=UTF-8’。语法为:client.setRequestHeader(header, value)。
我们可能需要设置的请求头为:Cookie、Cookie2、Host、Keep-Alive、Upgrade、Content-Type等。
此外,为了防止等待响应时间过长,我们可以设置client.timeout来设置等待时间,单位为毫秒。

处理数据并发送

新建了xhr对象,启动,并设置相关的请求头后,我们要对要发送的数据进行处理并发送。语法为:client.send([data = null])

  • 通过JSON.stringify()可以将对象转换为json数据。在解析json数据时使用JSON.parse()。
  • 如果xhr方法为GET或HEAD,忽略传入的data,设为null。
  • 如果发送的数据为对象,将对象类型作为要发送的值,如object,则发送主体为[object object]
  • 如果发送的数据为string,将Content-Type设为”text/plain;charset=UTF-8”。(注意,json也为string类型,所以发送json时,要设置请求头的内容类型)
  • 还可以发送document、FormData或ArrayBufferView类型

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
```

## 发送请求的方法
通常我们像一个url发送请求有三种方法,通过路径、query以及数据请求主体。
* 通过路径。我们制定url并不意味着这个url路径就存在。路径也可以作为请求而存在,并通过RESTful的设计,与GET、POST、PUT、DELETE四个方法结合,实现增删改查。[RESTful维基](https://www.wikiwand.com/zh/REST)
* 通过query。在使用GET方法追加请求信息时必须使用此方法。即在url后追加?key=value。
* 通过数据体。即通过数据处理,并将内容通过send(data)方法发送。GET和HEAD发送不能采用这种方式,因为会忽略data。

## GET请求和POST请求
* GET是最常见的请求类型,最常用于向服务器查询某些信息。使用频率仅次于GET的是POST请求,通常用于向服务器发送应该被保存的数据。
* GET方法不能修改服务器的内容,是绝对安全的,但要修改服务器内容,不能使用GET。而POST方法可以修改服务器的内容。
* GET将查询字符串参数值追加到URL的末尾(不能使用请求主体方式提交)。查询字符串中每个参数的名称和值都必须使用encodeURIComponent()进行编码。POST请求应该把数据作为请求的主体提交。
* POST请求的主体可以包含非常多的数据。而GET追加的字符串有限制(由于浏览器等限制)。
* GET方法将查询字符串追加到url后,相对不安全。最安全的是使用https。
* //有一个方法会缓存内容

## XMLHttpRequest 2级
#### FormData

var data = new FormData(); //方法1,先新建,再使用append方法添加
data.append(“name”,”liming”); //append()方法接收两个参数,属性和值

data = new FormData(document.form[0]); //方法2,直接传入表单,自动转换

xhr.send(data); //可以直接将formdata实例作为请求传入后台
```

超时设定

通过xhr.timeout=1000(1秒)属性设置超时。再通过xhr.ontimeout:function(){}设置超时响应事件。

进度事件

W3C定义了与客户服务器通信有关的事件(这些事件目前也被其他API借鉴)。有以下6个进度事件:

  1. loadstart:在接收到响应数据的第一个字节时触发
  2. progress:在接收响应期间持续不断地触发。可以动态地更新HTML元素的内容。如何相应头部有Content-Length字段,可以计算接收到的数据的百分比。
  3. error:在请求发生错误时触发
  4. abort: 在因为调用abort()方法时而终止连接时触发
  5. load:在接收到完整的响应数据时触发。不管状态如何,所以要检查status属性,确定数据可用性
  6. loadend:在通信完成或者触发error、abort、load事件后触发

跨域资源共享

通过XHR实现Ajax通信的一个主要限制,来源于跨域安全策略。默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源。CORS是W3C的一个工作草案,定义了在必须访问跨域资源时,浏览器与服务器应该如何沟通,其基本思想是:利用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。除此外,还有其他跨域方法:

  1. 图像Ping,还有一种跨域请求技术是使用<\img>标签。一个网页可以从任何网页中加载图像,不用担心是否跨域。
  2. JSONP。是应用JSON的一种新方法,它由两部分组成:回调函数和数据,它非常简单易用。
  3. Comet。是一种更高级的Ajax技术。Ajax是一种从页面向服务器请求数据的技术,而Comet则是一种服务器向页面推送数据的技术。由于其实时性,非常适合处理体育比赛的分数和股票报价。
  4. SSE(服务器发送事件):围绕只读Comet交互推出的API或者模式。SSE API用于创建到服务器的单向连接,服务器可以通过连接发送任意数量的数据。
  5. Web Sockets:最令人津津乐道的新浏览器API,目标是在一个单独的持久连接上提供全双工、双向通信。它非常适合移动应用。

安全

为确保通过XHR访问的URL安全,通行的做法就是验证发送请求者是否有权限访问相应的资源。有以下几种方式可供选择:

  • 要求以SSL连接来访问可以通过XHR请求的资源
  • 要求每一次请求都要附带经过相应算法计算得到的验证码
  • 要求发送POST而不是GET请求——容易改变
  • 检查来源URL以确定是否可信——来源记录容易伪造
  • 基于cookie信息进行验证——容易伪造