400-650-7353
1、简介
浏览器与服务器之间,采用 HTTP 协议通信。用户在浏览器地址栏键入一个网址,或者通过网页表单向服务器提交内容,这时浏览器就会向服务器发出 HTTP 请求。
1999年,微软公司发布 IE 浏览器5.0版,第一次引入新功能:允许 JavaScript 脚本向服务器发起 HTTP 请求。这个功能当时并没有引起注意,直到2004年的 Gmail 发布和2005年的 Google Map 发布,才引起广泛重视。
2005年2月,AJAX 这个词第一次正式提出,它是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。后来,AJAX 这个词就成为 JavaScript 脚本发起 HTTP 通信的代名词。也就是说,只要用脚本发起通信,就可以叫做 AJAX 通信。W3C 也在2006年发布了它的国际标准。
AJAX发起请求,具体包括以下几个步骤:
1.创建 XMLHttpRequest 实例
2.发出 HTTP 请求
3.接收服务器传回的数据
4.更新网页数据
概括起来,就是一句话,AJAX 通过原生的XMLHttpRequest对象发出 HTTP 请求,得到服务器返回的数据后,再进行处理。现在,服务器返回的都是 JSON 格式的数据,XML 格式已经过时了,但是 AJAX 这个名字已经成了一个通用名词,字面含义已经消失了。
2、主要接口
XMLHttpRequest对象是AJAX的主要接口,它本身是一个构造函数,可以使用new命令生成实例,它没有任何参数。
- var xhr = new XMLHttpRequest();
有了xhr实例,就可以调用它下面的open方法。
- xhr.open('GET', '请求url地址', true);
然后,指定回调函数,监听通信状态的变化。一旦xhr的readyState属性状态发生变化,就会调用该函数。
- xhr.onreadystatechange = function (){ }
最后调用send(),实际发出 HTTP 请求。
- xhr.send();
拿到服务器返回的数据后,AJAX 不会刷新整个网页,而是只更新网页里面的相关部分,从而不打断用户正在做的事情。
当然,AJAX只能向同源网址(协议、域名、端口都相同)发出 HTTP 请求,如果发出跨域请求,就会报错。
- var xhr = new XMLHttpRequest();
- xhr.open('GET', '请求url地址', true);
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4) {
- if (xhr.status === 200) {
- console.log(xhr.responseText); // 取得数据
- } else {
- console.error(xhr.statusText); // 提示信息
- }
- }
- };
- xhr.send();
3、XMLHttpRequest的实例属性
- var xhr = new XMLHttpRequest();
我们下面讨论的都是XMLHttpRequest下面的属性,以xhr代指实例。
1、xhr.readyState
表示实例对象的当前状态。该属性只读。
AJAX通信的过程中,会有5个阶段,分别用0--4的数字代表。xhr.readyState返回数字,代表当前通信到了哪个阶段。
• 0:表示 XMLHttpRequest 实例已经生成,但是实例的open()方法还没有被调用。
• 1:表示open()方法已经调用,但是实例的send()方法还没有调用,仍然可以使用实例的setRequestHeader()方法,设定 HTTP 请求的头信息。
• 2:表示实例的send()方法已经调用,并且服务器返回的头信息和状态码已经收到。
• 3:表示正在接收服务器传来的数据体(body 部分)。这时,如果实例的responseType属性等于text或者空字符串,responseText属性就会包含已经收到的部分信息。
• 4:表示服务器返回的数据已经完全接收,或者本次接收已经失败。
通信过程中,只要实例的状态发生变化,它的xhr.readyState属性值就会发生变化,这个值每一次变化,都会触发onreadystatechange事件。而通常情况下,我们关心的是状态为4的时候,代表发起的HTTP请求已经成功。
2、xhr.status 和 xhr.statusText
status属性返回一个整数,表示服务器回应的 HTTP 状态码。一般来说,如果通信成功的话,这个状态码是200;如果服务器没有返回状态码,那么这个属性默认是200。该属性只读。
• 200, OK,访问正常
• 301, Moved Permanently,永久移动
• 302, Move temporarily,暂时移动
• 304, Not Modified,未修改
• 307, Temporary Redirect,暂时重定向
• 401, Unauthorized,未授权
• 403, Forbidden,禁止访问
• 404, Not Found,未发现指定网址
• 500, Internal Server Error,服务器发生错误
只有2xx和304的状态码,表示服务器返回是正常状态。
statusText属性返回一个字符串,表示服务器发送的状态提示。不同于status属性,该属性包含整个状态信息,比如“OK”和“Not Found”。如果服务器没有返回状态提示,该属性的值默认为”“OK”。该属性为只读属性。
- var xhr = new XMLHttpRequest();
- xhr.open('GET', '请求url地址', true);
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4) {
- if ((xhr.status >= 200 && xhr.status < 300) || (xhr.status ===
- 304)) {
- // 处理服务器的返回数据
- } else {
- // 出错
- }
- }
- };
- xhr.send();
3、xhr.responseType
该属性是一个字符串,表示希望服务器返回数据的类型。
这个属性是可写的,可以在调用open()方法之后、调用send()方法之前,设置这个属性的值,告诉服务器返回指定类型的数据。如果responseType设为空字符串,就等同于默认值text。
responseType属性可以是:
• "arraybuffer":ArrayBuffer 对象,表示服务器返回二进制数组。
• "blob":Blob 对象,表示服务器返回二进制对象。
• "document":Document 对象,表示服务器返回一个文档对象。
• "json":JSON 对象。
• "text":字符串,表示服务器返回文本数据。
• ""(空字符串):等同于"text"。
text类型适合大多数情况,而且直接处理文本也比较方便。
document类型适合返回 HTML / XML 文档的情况
blob类型适合读取二进制数据,比如图片文件。
json,浏览器就会自动对返回数据调用JSON.parse()方法。也就是说,从xhr.response属性(注意,不是xhr.responseText属性)得到的不是文本,而是一个 JSON 对象。
4、xhr.response
该属性表示服务器返回的数据体(即 HTTP 回应的 body 部分),它可能是任何数据类型。具体的类型由xhr.responseType属性决定。该属性只读。如果本次请求没有成功或者数据不完整,该属性等于null
- var xhr = new XMLHttpRequest();
- xhr.open('GET', '请求url地址', true);
- xhr.onreadystatechange = function () {
- // readyState状态为4,代表请求完成
- if(xhr.readyState === 4){
- // 返回的数据
- console.log(xhr.response);
- }
- };
- xhr.send();
5、xhr.responseText
该属性返回从服务器接收到的字符串,该属性为只读。只有 HTTP 请求完成接收以后,该属性才会包含完整的数据。
- var xhr = new XMLHttpRequest();
- xhr.open('GET', '请求url地址', true);
- xhr.responseType = 'text';
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4 && xhr.status === 200) {
- // 请求成功的数据
- console.log(xhr.responseText);
- }
- };
- xhr.send();
6、xhr.timeout
设置超时,该属性接收一个整数,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止。如果该属性等于0,就表示没有时间限制。
- var xhr = new XMLHttpRequest();
- xhr.open('GET', '请求url地址', true);
- xhr.onreadystatechange = function () {
- // readyState状态为4,代表请求完成
- if (xhr.readyState === 4) {
- console.log(xhr.response);
- }
- };
- // 指定 10 秒钟超时
- xhr.timeout = 10 * 1000;
- xhr.send();
7、xhr.upload
XMLHttpRequest 不仅可以发送请求,还可以发送文件,这就是 AJAX 文件上传。发送文件以后,通过xhr.upload属性可以得到一个对象,通过观察这个对象,可以得知上传的进展。主要方法就是监听这个对象的各种事件:loadstart、loadend、load、abort、error、progress、timeout。文件上传时,对upload属性指定progress事件的监听函数,即可获得上传的进度。
- var progressBar =document.querySelector('progress'); //展示进度的元素
- var xhr = new XMLHttpRequest();
- xhr.open('POST', '请求url地址', true);
- xhr.upload.onprogress = function (e) {
- if (e.lengthComputable) {
- progressBar.innerText = (e.loaded / e.total) * 100;
- } else {
- console.log('无法计算进展');
- }
- };
- xhr.send(上传的文件对象);
4、XMLHttpRequest的实例方法
- var xhr = new XMLHttpRequest();
我们下面讨论的都是XMLHttpRequest下面的方法,以xhr代指实例。
1、xhr.open()
该方法用于指定 HTTP 请求的参数,它一共可以接受五个参数。
- xhr.open(method, url, async, user, password);
• method:表示 HTTP 动词方式,比如GET、POST、PUT、DELETE、HEAD等。
• url: 表示请求发送目标 URL。
• async: 布尔值,表示请求是否为异步,默认为true。如果设为false,则send()方法只有等到收到服务器返回了结果,才会进行下一步操作。该参数可选。
• user:表示用于认证的用户名,默认为空字符串。该参数可选。
• password:表示用于认证的密码,默认为空字符串。该参数可选。
2、xhr.send()
该方法用于实际发出 HTTP 请求。它的参数是可选的,如果不带参数,就表示 HTTP 请求只包含头信息,也就是只有一个 URL,典型例子就是 GET 请求;如果带有参数,就表示除了头信息,还带有包含具体数据的信息体,典型例子就是 POST 请求。
注意:所有 XMLHttpRequest 的监听事件,都必须在send()方法调用之前设定。
3、xhr.setRequestHeader()
该方法用于设置浏览器发送的 HTTP 请求的头信息。该方法必须在open()之后、send()之前调用。
该方法接受两个参数。第一个参数是字符串,表示头信息的字段名,第二个参数是字段值。
- xhr.setRequestHeader('Content-Type', 'multipart/form-data');
4、xhr.abort()
该方法用来终止已经发出的 HTTP 请求。调用这个方法以后,readyState属性变为4,status属性变为0。
- var xhr = new XMLHttpRequest();
- xhr.open('GET', '请求url地址', true);
- setTimeout(function () {
- if (xhr) {
- xhr.abort();
- xhr = null;
- }
- }, 5000);
5、XMLHttpRequest实例的事件
1、xhr.onreadyStateChange 事件
该属性指向一个监听函数,只要xhr.readyState的属性发生变化,就会触发该函数。
- var xhr = new XMLHttpRequest();
- xhr.open('GET', '请求url地址', true);
- xhr.onreadystatechange = function () { };
- xhr.send();
2、xhr.onprogress 事件
上传文件时,XMLHTTPRequest 实例对象本身和实例的upload属性,都有一个progress事件,会不断返回上传的进度。
- var xhr = new XMLHttpRequest();
- xhr.open();
- xhr.onprogress = function (e) {
- if (e.lengthComputable) {
- var percentComplete = e.loaded / e.total;
- } else {
- console.log('无法计算进展');
- }
- }
3、xhr.onload 事件、xhr.onerror 事件、xhr.onabort 事件
load 事件表示服务器传来的数据接收完毕,error 事件表示请求出错,abort 事件表示请求被中断(比如用户取消请求)。
- var xhr = new XMLHttpRequest();xhr.open();
- function transferComplete() {
- console.log('数据接收完毕');
- }
- function transferFailed() {
- console.log('数据接收出错');
- }
- function transferCanceled() {
- console.log('用户取消接收');
- }
- xhr.addEventListener('load', transferComplete);
- xhr.addEventListener('error', transferFailed);
- xhr.addEventListener('abort', transferCanceled);
4、xhr.onloadend 事件
abort、load和error这三个事件,会伴随一个loadend事件,表示请求结束,但不知道其是否成功。
- var xhr = new XMLHttpRequest();
- xhr.open();
- function loadEnd(e) {
- console.log('请求结束,状态未知');
- }
- xhr.addEventListener('loadend', loadEnd);
5、xhr.ontimeout 事件
服务器超过指定时间还没有返回结果,就会触发 timeout 事件。