概述:
AJAX( Asynchronous JavaScript and XML)即异步的 JavaScript 和 XML,是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
如在访问新浪微博时,看到一大半了点击底部的加载更多,可以继续浏览下面的内容,同时页面并不会整体刷新;但若没有异步更新 ,每次点击加载更多,网页都要重新刷新从头开始看,这体验就太糟糕了!
原理(发送 Ajax 请求的五个步骤)
(1)创建异步对象,即 XMLHttpRequest 对象。
(2)使用 open 方法设置请求参数。open(method, url, async)
。【参数解释:请求的方法(get/post)、请求的 url、是否异步(默认为 true)。】
(3)发送请求:send()
。
(4)注册事件:注册 onreadystatechange 事件,状态改变时就会调用。如果要在数据完整请求回来的时候才调用,需要手动写一些判断的逻辑。
(5)服务端响应,获取返回的数据。
发送带参数(a=1,b=2)的get请求代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> AJAX </title>
</head>
<body>
<script>
//1.创建对象
const xhr = newXMLHttpRequest();
//2.初始化设置请求方法和url
xhr.open('GET','./ajax.php?a=1&b=2');
//3.发送
xhr.send();
//4.注册onreadystatechange事件,状态改变时就会调用。
//onwhen当....时候
//readystate是xhr对象中的属性,表示状态01234
//change改变
xhr.onreadystatechange = function(){
//判断(服务端返回了所有的结果)
if(xhr.readyState === 4){
//判断响应状态码 2xx成功
if(xhr.status >= 200&&xhr.status < 300){
//处理结果行头空行体 响应
//console.log(xhr.status);//状态码
//console.log(xhr.statusText);//状态字符串
//console.log(xhr.getAllResponseHeaders());//所有响应头
console.log('数据返回成功:')
console.log(xhr.response);//响应体
}
}
}
</script>
</body>
</html>
POST 请求时注意:
如果要像form 表单提交数据那样使用 POST 请求,就需要使用 XMLHttpRequest 对象的 setRequestHeader()方法来添加 HTTP 头。然后在 send() 方法中添加想要发送的数据:
//2. 初始化 设置类型与 URL
xhr.open('POST', 'http://127.0.0.1:8000/server');
//设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','xiaobaimu');
onreadystatechange 事件
注册 onreadystatechange 事件后,每当状态码readyState 改变时,就会调用 onreadystatechange 函数。readyState:
-
0: 请求未初始化
-
1: 服务器连接已建立,配置信息已经完成
-
2: 请求已接收
-
3: 请求处理中,正在解析响应内容
-
4: 请求已完成,且响应已就绪
HTTP状态码:
所以当 http 状态码status 为 200 ~ 299时,才请求处理成功。
封装ajax
为方便使用一般会封装成一个函数,然后通过回调函数处理成功和失败的逻辑:
//封装Ajax为公共函数:传入回调函数success和fail
function Ajaxfun (url,success,fail){
//1、创建xhrRequest对象
const xhr;
if(window.xhrRequest){
xhr = newxhrRequest();
}else{
//兼容IE5、IE6,可以不写
xhr = newActiveXObject('Microsoft.xhr');
}
//2、发送请求
xhr.open('GET',url,true);
xhr.send();
//3、服务端响应
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 300){
varobj=JSON.parse(xhr.responseText);
console.log('数据返回成功:'+Jobj);
success&&success(xhr.responseText);
}else{
//这里的&&符号,意思是:如果传了fail参数,就调用后面的fail();
fail&&fail(newError('接口请求失败'));
}
}
}
//单次调用ajax
Ajaxfun('a.json',(res)=>{
console.log(res);
});
//多次调用ajax。接口请求顺序:a-->b-->c
Ajaxfun('a.json',(res)=>{
console.log(res);
Ajaxfun('b.json',(res)=>{
console.log(res);
Ajaxfun('c.json',(res)=>{
console.log(res);
});
});
});
AJAX、axios、fetch的区别
AJAX:最早出现的发送后端请求技术,属于原始js中,核心使用XMLHttpRequest 对象,多个请求之间如果有先后关系的话,就会出现回调地狱(如上述代码中的多次调用)原生ajax,现在基本已经没人使用。
axios:一个基于Promise的HTTP库,可以用在浏览器和node.js中,它底层还是基于XMLHttpRequest对象的,你可以认为它是一个方便的封装库,除了基础请求数据,它还增加了如下功能:
-
对PromiseAPI的支持
-
支持请求拦截和响应、转换请求数据和响应数据、取消请求
-
可以自动转换JSON数据
-
支持防御XSRF
fetch:fetch是原生的js对象,但不是XMLHttpRequest对象,它不依赖浏览器,fetch提供了一个理解的请求替换方案,可以提供给其它技术使用。fetch和ajax的本质区别:
-
fetch返回的是Promise,所以如果HTTP状态码是404之类的,fetch也是成功返回的,只有在网络连接错误的情况下,才会reject
-
fetch不发送cookies
fetch的请求写法会比AJAX简单许多,最主要的问题是,无法区分HTTP状态码了,这个在编程时还是比较常用的,所以我们目前还是使用axios比较多,而很少使用fetch。