# AJAX原理
传统的form表单提交,只要提交submit,网页就会刷新一下,提交一次请求。一次请求对应一个页面,没有办法在页面进来后,在当前页面再次请求数据。而ajax 异步网络请求,可以进行局部刷新,在页面进来后,可以再次进行请求数据而不刷新页面。
流程:
- 通过XMLHttpRequest对象new一个ajax实例
- 使用open方法初始化请求
- 使用send方法发送数据请求
- 调用onreadystatechange事件监听ajax状态
- 通过ajax状态xhr.readyState和http状态码xhr.status判断是否获取成功
- 通过xhr.responseText获取返回结果
XMLHttpRequest()对象
通过new XMLHttpRequest()创建一个ajax实例,但IE6一下不支持这个对象,IE6及以下以插件的形式ActiveXObject('Microsoft.XMLHTTP')来获取。
兼容性写法:
xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open()方法
xhr.open()初始化请求,并判断请求方式,接收三个参数。
xhr.open(method, url, bool):
- method: 定义请求的方式 get post
- url:向后台请求的接口地址
- bool:是否使用异步 默认是true
xhr.send()方法
xhr.send()方法向后端发送请求,GET方法直接调用,使用POST时,在里面添加请求的参数,与open方法拼接成一个完整的地址。
xhr.setRequestHeader()
设置 HTTP 请求头的值。必须在 open() 之后、send() 之前调用 setRequestHeader() 方法。
xhr.setRequestHeader(header, value);
xhr.abort()方法
xhr.abort()终止请求
xhr.onreadystatechange事件
监听xhr请求状态readyState的改变,通过该方法监听xhr.readyState和xhr.status的状态来判断请求是否成功。
xhr.onreadystatechange = function() {
if(xhr.readyState==4 && xhr.status==200){
console.log(xhr.responseText);
}else{
console.log(xhr.status+xhr.statusText);
}
}
xhr.readyState
返回ajax请求当前所处的状态,一个xhr请求总处于下面几种状态中
- 0、(初始化)还没有调用open()方法
- 1、(载入)已调用open()方法,正在发送请求
- 2、(载入完成)send()方法完成,已收到全部响应内容
- 3、(解析)正在解析响应内容
- 4、(完成)响应内容解析完成,可以在客户端调用了
xhr.status
服务器(请求资源)的状态,http的状态码
- 1xx: 信息反馈
- 2xx: 请求成功
- 3xx: 重定向
- 4xx: 客户端错误
- 5xx: 服务端错误
xhr.responseText
接收后台返回的文本数据。后台接收请求后,返回的数据格式为字符串。
get请求
通过url地址进行传输,请求地址都方在xhr.open()方法中,参数放在url后面,以?来连接值 以key=value为例,多个值以&来连接起来。
特点:
- 1、由于url路径大小的限制 get方法后面的数据不能太多
- 2、get方法会被缓存
- 如何解决缓存问题?传参的时候,加上随机数
- 怎么生成随机数 常见的做法,用一个时间戳做随机数 new Date().getTime()
- 传的如果是中文 最好转化成unicode encodeURI()
- 3、get不安全
http://localhost/ajax/02.get.php?user=111&age=222
post请求
post方法通过服务器进行传输,url放在xhr.open()方法中,参数放在xhr.send()方法中来进行发送请求,以key1=value1&key2=value2格式发送。
特点:
- 1、安全性好一点
- 2、理论上讲在不考虑服务器带宽压力的情况下,post数据大小不限
- 3、post 不会被缓存
GET请求:
var url = 'http://www.abc.com/api';
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('get', url+'?page=1&num=10&'+new Date().getTime()); // 添加时间戳,防止缓存
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText); // 获取到数据,渲染
}else{
console.log(xhr.status+xhr.statusText);
}
}
POST请求:
var url = 'http://www.abc.com/api/login';
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('post', url);
xhr.send('user='+user.name+'&age='+user.age);
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText);
}else{
console.log(xhr.status+xhr.statusText);
}
}
ajax封装:
/*
params: {
method: ''
url: '',
data: {
},
success: function(reponse){},
fail: function(error){}
}
*/
function ajax(params) {
var xhr = null;
xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
var data = '',
url = params.url;
if(params.data) {
// 拼接参数
for(var key in params.data) {
data += key + '=' + params.data[key] + '&';
}
data = data.slice(data.lastIndexOf('&')); // 去掉多余的&
}
if(data && params.method.toLowerCase() === 'get') {
url += '?' + data;
}
xhr.open(params.method.toLowerCase(), url, true);
if(data && params.method.toLowerCase() === 'get') {
xhr.send();
} else {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);
}
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
params.success && params.success(JSON.parse(xhr.responseText));
} else {
var error = {
code: xhr.status,
message: xhr.statusText
}
params.fail && params.fail(error);
}
};
}
// 使用
ajax({
url: '',
method: 'get',
data:{
name: 'xxx',
age: 18
}
success:function(data){
console.log(data)
}
fail:function(error){
console.log(error)
}
});
promise封装:
/*
params: {
method: ''
url: '',
data: {
}
}
*/
function ajax(params) {
return new Promis(function(resolve, reject) {
var xhr = null;
xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
var data = '',
url = params.url;
if(params.data) {
// 拼接参数
for(var key in params.data) {
data += key + '=' + params.data[key] + '&';
}
data = data.slice(data.lastIndexOf('&')); // 去掉多余的&
}
if(data && params.method.toLowerCase() === 'get') {
url += '?' + data;
}
xhr.open(params.method.toLowerCase(), url, true);
if(data && params.method.toLowerCase() === 'get') {
xhr.send();
} else {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);
}
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(JSON.parse(xhr.responseText))
} else {
var error = {
code: xhr.status,
message: xhr.statusText
}
reject(error)
}
}
})
}
// 使用
ajax({
url: '',
method: 'get',
data:{
name: 'xxx',
age: 18
}
}).then(function(data) {
console.log(data)
return ajax({data: data})
}).then(function(data) {
console.log(data)
}).catch(function(error) {
console.log(error)
})
参考链接: