AJAX简介
AJAX的全称是Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。AJAX可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页。同时可以实现异步更新(不重新加载整个网页的情况下,对网页的某部分进行更新),而传统的一般都是同步更新(更新内容,必须重载整个网页面)。
注: AJAX 只能在同源的情况下使用,但可以通过CORS放权给指定源从而实现在非同源的情况下使用。
AJAX的步骤
- 创建 XMLHttpRequest 实例
- 发出 HTTP 请求
- 接收服务器传回的数据
- 更新网页数据
异步请求和同步请求
同步请求:
- 发出请求后,浏览器本身不能做其他动作
- 必须得等到请求完成返回数据之后,才会执行后续的代码
- JS在执行AJAX的时候,其他页面均不能执行,相当于代码在排队执行
异步请求:
- 发出请求的同时,浏览器可以继续做任何事,
- Ajax发送请求不会影响页面的加载与用户的操作
XMLHttpRequest 对象
XMLHttpRequest
对象是 AJAX 的主要接口,用于浏览器与服务器之间的通信。尽管名字里面有XML
和Http
,但实际上可以使用多种协议(例如file
或ftp
),发送任何格式的数据(包括字符串和二进制)。
示例:
var xhr = new XMLHttpRequest();
// XMLHttpRequest本身是一个构造函数,可以使用new命令生成实例,但没有任何参数
xhr.onreadystatechange = function(){
if (xhr.readyState === 4){
if (xhr.status === 200){
console.log(xhr.responseText);
} else {
console.error(xhr.statusText);
}
}// 通信成功时,状态值为4,网页状态值为200
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
// 上面是错误回显
xhr.open('GET', '/endpoint', true);
// open('提交方式', '指定连接的服务器网址', '开启异步请求')
xhr.send(null);
XMLHttpRequest 的实例属性
XMLHttpRequest.readyState属性
XMLHttpRequest.readyState
返回一个整数,表示实例对象的当前状态,该readyState
属性只读,存在返回以下值:
- 0,表示 XMLHttpRequest 实例已经生成,但是实例的
open()
方法还没有被调用。 - 1,表示
open()
方法已经调用,但是实例的send()
方法还没有调用,仍然可以使用实例的setRequestHeader()
方法,设定 HTTP 请求的头信息。 - 2,表示实例的
send()
方法已经调用,并且服务器返回的头信息和状态码已经收到。 - 3,表示正在接收服务器传来的数据体(body 部分)。这时,如果实例的
responseType
属性等于text
或者空字符串,responseText
属性就会包含已经收到的部分信息。 - 4,表示服务器返回的数据已经完全接收(成功)或者本次接收已经失败。
示例:
var xhr = new XMLHttpRequest();
if (xhr.readyState === 4) {
// 请求结束,处理服务器返回的数据
} else {
// 显示提示“加载中……”
}
XMLHttpRequest.onreadystatechange属性
XMLHttpRequest.onreadystatechange
属性指向一个监听函数。readystatechange
事件发生时(实例的readyState
属性变化),就会执行这个属性。
如果使用实例的abort()
方法,终止 XMLHttpRequest 请求,也会造成readyState
属性变化,随后调用XMLHttpRequest.onreadystatechange
属性。
示例:
var xhr = new XMLHttpRequest();
xhr.open( 'GET', 'http://example.com' , true );
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4 || xhr.status !== 200) {
return;
}
console.log(xhr.responseText);
};
xhr.send();
XMLHttpRequest.response属性
XMLHttpRequest.response
属性表示服务器返回的数据体(即 HTTP 回应的 body 部分)。它可能是任何数据类型,比如字符串、对象、二进制对象等等,具体的类型由XMLHttpRequest.responseType
属性决定,该response
属性只读。
示例:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
handler(xhr.response);
}
}
XMLHttpRequest.responseType属性
XMLHttpRequest.responseType
属性是一个字符串,表示服务器返回数据的类型,该属性可写。
XMLHttpRequest.responseType
属性存在以下值:
- “”(空字符串):等同于
text
,表示服务器返回文本数据。 - “arraybuffer”:
ArrayBuffer
对象,表示服务器返回二进制数组。 - “blob”:
Blob
对象,表示服务器返回二进制对象。 - “document”:
Document
对象,表示服务器返回一个文档对象。 - “json”:
JSON
对象。 - “text”:字符串。
XMLHttpRequest.timeout,XMLHttpRequestEventTarget.ontimeout属性
XMLHttpRequest.timeout
属性返回一个整数,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止。如果该属性等于0,就表示没有时间限制。
XMLHttpRequestEventTarget.ontimeout
属性用于设置一个监听函数,如果发生 timeout 事件,就会执行这个监听函数。
示例:
var xhr = new XMLHttpRequest();
var url = '/server';
xhr.ontimeout = function () {
console.error('The request for ' + url + ' timed out.');
};
xhr.onload = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// 处理服务器返回的数据
} else {
console.error(xhr.statusText);
}
}
};
xhr.open('GET', url, true);
// 指定 10 秒钟超时
xhr.timeout = 10 * 1000;
xhr.send(null);
事件监听属性
XMLHttpRequest 对象可以对以下事件指定监听函数:
- XMLHttpRequest.onloadstart:loadstart 事件(HTTP 请求发出)的监听函数
- XMLHttpRequest.onprogress:progress事件(正在发送和加载数据)的监听函数
- XMLHttpRequest.onabort:abort 事件(请求中止,比如用户调用了
abort()
方法)的监听函数 - XMLHttpRequest.onerror:error 事件(请求失败)的监听函数
- XMLHttpRequest.onload:load 事件(请求成功完成)的监听函数
- XMLHttpRequest.ontimeout:timeout 事件(用户指定的时限超过了,请求还未完成)的监听函数
- XMLHttpRequest.onloadend:loadend 事件(请求完成,不管成功或失败)的监听函数
注:其中仅有progress
事件的监听函数存在事件对象参数,该对象有三个属性:
loaded
属性返回已经传输的数据量total
属性返回总的数据量lengthComputable
属性返回一个布尔值,表示加载的进度是否可以计算。
示例:
xhr.onload = function() {
var responseText = xhr.responseText;
console.log(responseText);
// process the response.
};
xhr.onabort = function () {
console.log('The request was aborted');
};
xhr.onprogress = function (event) {
console.log(event.loaded);
console.log(event.total);
};
xhr.onerror = function() {
console.log('There was an error!');
};
XMLHttpRequest.withCredentials
XMLHttpRequest.withCredentials
属性是一个布尔值,表示跨域请求时,用户信息(比如 Cookie 和认证的 HTTP 头信息)是否会包含在请求之中,默认为false
(用户信息不会包含在请求之中),可以改为true
(实施跨域 AJAX 请求发送 用户信息)。
注:此项属性是在非同源的情况下才需要添加
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);
服务器必须显式返回Access-Control-Allow-Credentials
这个头信息,才能让这个属性生效
Access-Control-Allow-Credentials: true
// CORS中的withCredentials属性
需要在连接数据库的文件中添加下方语句()
Access-Control-Allow-Origin: http://api.bob.com
// CORS中的Access-Control-Allow-Origin字段
XMLHttpRequest 实例的事件
readyStateChange 事件
readyState
属性的值发生改变,就会触发 readyStateChange 事件。
可以通过onReadyStateChange
属性,指定这个事件的监听函数,对不同状态进行不同处理。
progress 事件
上传文件时,XMLHttpRequest 实例对象本身和实例的upload
属性,都有一个progress
事件,会不断返回上传的进度。
示例:
var xhr = new XMLHttpRequest();
function updateProgress (oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded / oEvent.total;
} else {
console.log('无法计算进展');
}
}
xhr.addEventListener('progress', updateProgress);
xhr.open();
load 事件、error 事件、abort 事件
load 事件表示服务器传来的数据接收完毕
error 事件表示请求出错
abort 事件表示请求被中断(比如用户取消请求)。
示例:
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', transferComplete);
xhr.addEventListener('error', transferFailed);
xhr.addEventListener('abort', transferCanceled);
xhr.open();
function transferComplete() {
console.log('数据接收完毕');
}
function transferFailed() {
console.log('数据接收出错');
}
function transferCanceled() {
console.log('用户取消接收');
}
loadend 事件
abort
、load
和error
这三个事件,会伴随一个loadend
事件,表示请求结束,但具体状态未知。
示例:
xhr.addEventListener('loadend', loadEnd);
function loadEnd(e) {
console.log('请求结束,状态未知');
}
timeout 事件
服务器超过指定时间还没有返回结果,就会触发 timeout 事件。
CORS 通信(简介)
CORS 是一个 W3C 标准,全称是“跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨域的服务器,发出XMLHttpRequest
请求,从而克服了 AJAX 只能同源使用的限制。需要服务器和浏览器同时支持才可使用。
两种请求
CORS 请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
同时满足以下两大条件,就属于简单请求:
(1)请求方法是以下三种方法之一:
- HEAD
- GET
- POST
(2)HTTP 的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。
简单请求就是简单的 HTTP 方法与简单的 HTTP 头信息的结合。
非简单请求是那种对服务器提出特殊要求的请求,比如请求方法是PUT
或DELETE
,或者Content-Type
字段的类型是application/json
。