ajax原理分析
ajax是通过XMLHttpRequest对象和服务器进行通信的一种方式,就像我们在浏览器地址栏输入url,然后服务器返回页面一样,只不过ajax给了我们充分的自由,让我们可以选择何时发送http请求,以何种方式发以及发什么。
首先,创建一个XMLHttpRequest对象:
function createXHR() { return new XMLHttpRequest(); }
IE从7开始支持XHR对象,我不想再支持IE6了,所以你懂的。
代码范式
xhr.open(method, url, isAsyn); xhr.send(data);
xhr.open()没有发送请求,而是准备好了一个即将发送的请求。
xhr.send()的参数是请求的参数,如果没有,传入null,一旦调用了send(),请求就发给服务器了。
注意:url不能跨域
请求发送出去后,js会等待请求返回。当收到一个返回后,XHR对象会被填入数据,数据格式如下:
- responseText: 不论content type是什么,这个属性都会被填入响应的正文
- responseXML: 如果响应的content type为"text/xml" 或 "application/xml",返回的数据就会包含一个XML DOM文档,否则是null
- status: HTTP状态码
- statusText: HTTP状态码的描述(可以无视它,因为各浏览器的实现不一样)
请求返回后,第一步要做的是检测状态码确保请求是成功的:
- 状态码在200-300之间表示请求成功了,如果content type设置正确的话,可以拿到responseText或responseXML;
- 状态码是304表示资源没有被改动过,请求直接从浏览器的缓存中拿数据;
var status = xhr.status; if ((status >= 200 && status < 300) || status == 304) { // xhr.responseText }
同步异步
现在来看xhr.open()的第三个参数,是个布尔值,表示请求是否异步。
首先想想,为什么要这个参数?
如果请求是同步的,那么js会阻塞,一直等到请求返回才能继续往下执行,但如果这时网络出了问题,或者网络很慢,那整个网站都处于瘫痪状态,这个场景你懂的。
所以这个参数一般都是true。
既然请求是异步,那我们需要知道请求何时返回,这就要用到事件侦听(onreadystatechange),其中又用到readyState属性,它表示当前请求/响应的阶段,可能的值如下:
- 0: uninitialized,还没调用open()
- 1: open,调用了open(),但还没调用send()
- 2: sent,调用了send(),但请求还没返回
- 3: receiving,收到了部分响应数据
- 4: complete,收到了所有的响应数据,并且可用了
当readyState的值变化时,就会触发readystatechange事件,这时你可以检测readyState的值。通常我们感兴趣的值是4,为了兼容所有浏览器,我们要把onreadystatechange事件处理放在open()前面,如下:
var xhr = createXHR(); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { var status = xhr.status; if ((status >= 200 && status < 300) || status == 304) { alert(xhr.responseText); } else { alert('Request was unsuccessful: ' + xhr.status); } } }; xhr.open('get', 'example.txt', true); xhr.send(null);
如果在请求返回前,你想取消这次请求,使用xhr.abort();