近期在学习ajax技术,这里记录一下学习的收获。
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
一、ajax的几个步骤
要想利用ajax进行数据请求,需要以下几个步骤
1.创建XMLHttpRequest对象
所有现代的浏览器都支持 XMLHttpRequest 对象。而旧版本的IE5、IE6不支持,需要做兼容性。
var xhr;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xhr = new XMLHttpRequest();
}
else { // code for IE6, IE5
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
2.设置请求方式和请求地址
open函数需要三个参数,分别是,请求方式,请求地址,是否异步,一般不建议把第三个参数设为false(毕竟我们用ajax就为了它的异步)。
xhr.open("get", "test.php", true);
3.发送请求
简单的get请求只需要执行send函数即可,不需要参数(get的参数写在请求地址中)
xhr.send();
如果使用post请求,我们需要事先设置请求头,再发送数据
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(str);
这里的str是要发送的数据,必须为字符串,而且格式符合 key=value ,多组数据用 & 隔开,例如
str = "name=cheney&gender=secret";
4.监听状态变化
给xhr添加 onreadystatechange 事件监听状态变化,然后通过xhr.readyState判断响应状态。
存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
0 | 请求未初始化 |
1 | 服务器连接已建立 |
2 | 请求已接收 |
3 | 请求处理中 |
4 | 请求已完成,且响应已就绪 |
只有响应码为4 才说明请求完成。
5.处理返回结果
这里需要通过 xhr.status 判断响应类型,xhr.status 是此次http请求的响应码,当响应码为200到300之间或304(读取缓存)时,说明请求成功。
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr === 304) {
console.log('请求成功');
}
else {
console.log('请求失败');
}
}
};
6.接收返回的数据
ajax是用来异步请求数据的,所以一般会有数据返回。
返回的数据一般有两种类型,即 xml 和 json 。
这里就不多介绍 xml 和 json 了,需要了解的请移步百度。
(1)如果服务端数据返回的是 xml, 例如如下的数据
<person>
<name>张三</name>
<age>18</age>
<sex>male</sex>
</person>
那么我们在前端用 xhr.responseXML 接收,然后按照HTML的dom结构解析即可,例如 getElementsByTagName() 等函数都可以解析,这里就不赘述。
(2)如果服务端数据返回的是 json, 例如如下的数据
{"name":"张三","age":"18","sex":"male"}
实际json只是一个特殊格式的字符串,所以我们通过 xhr.responseText 接收,然后利用 JSON.parse() 解析。
obj = JSON.parse(xhr.responseText);
然后将获取到的数据渲染到页面上。
7.设置超时中断
有时候由于服务端或网络问题导致请求事件过长,那么客户端不能一直等待,需要设置超时中断请求。
只需要在请求开始设置定时器,定时时间到就执行 xhr.abort(); 中断请求。
8.设置时间戳
由于低版本浏览器在进行get请求时会认为同一url的返回结果相同,就不能实时返回服务端的结果,而是从缓存中取。所以一般在url中添加时间戳保证每次请求的URL都不同。
以上7,8两步非必需,只是为了完善这个过程而添加的,读者可以根据自己需要选择。
最后,我们将这个 ajax 请求的流程封装成方法,便于以后使用。
function ajax(option) {
// method, url, data, timeout, success, error
var xhr;
var str = data2str(option.data);
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
if (option.type.toLowerCase() === 'post') {
xhr.open(option.type, option.url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(str);
} else if (option.type.toLowerCase() === 'get') {
xhr.open(option.type, option.url + '?' + str, true);
xhr.send();
}
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
clearTimeout(timer);
if (xhr.status >= 200 && xhr.status < 300 || xhr === 304) {
option.success(xhr);
}
else {
option.error(xhr);
}
}
};
if (option.timeout) {
var timer = setTimeout(function () {
xhr.abort();
clearTimeout(timer);
}, option.timeout)
}
}
// 将对象转化成用于传输的字符串
function data2str(data) {
var res = [];
data.t = new Date().getTime();
for (var key in data) {
res.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
return res.join('&');
}