前端的技术发展速度非常的快,异步请求也是其重要的体现之一,从最早的原生XHR,再到JqueryAjax的统治时代,再到近来,fetch、axios等技术也开始出现并大量投入使用。
Ajax是指一种创建交互式网页应用的网页开发技术,并且可以做到无需重新加载整个网页的情况下,能够更新部分网页,也叫作局部更新。
使用ajax发送请求是依靠于一个对象,叫XmlHttpRequest
对象,通过这个对象我们可以从服务器获取到数据,然后再渲染到我们的页面上。现在几乎所有的浏览器都有这个对象,只有IE7以下的没有,而是通过ActiveXObject
这个对象来创建的。XmlHttpRequest对象有一些常见的方法:
方法 | 描述 |
---|---|
abort() | 停止当前请求 |
getAllResponseHeaders() | 把HTTP请求的所有响应首部作为键/值对返回 |
getResponseHeader(“header”) | 返回指定首部的串值 |
open(method,url) | 建立对服务器的调用,还有3个可选参数,是否异步、用户名、密码 |
send(content) | 向服务器发送请求 |
abort() | 停止当前请求 |
setRequestHeader(header, value) | 把指定首部设置为所提供的值。 |
1.创建XmlHttpRequest对象
2.调用open方法设置基本请求信息
3.设置发送的数据,发送请求
4.注册监听的回调函数
5.拿到返回值,对页面进行更新
其实get和post的请求方式大致是相同的,下面分别是get和post的示例代码:
get
<script>
//步骤一:创建异步对象
var xhr = new XMLHttpRequest();
//步骤二:设置请求的基本参数
xhr.open('get','test.php');
//步骤三:发送请求
xhr.send();
//步骤四:注册onreadystatechange监听事件,只要状态改变就会调用
xhr.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
//步骤五 如果能够进到这个判断 说明数据完美到手
console.log(ajax.responseText);//操作返回内容
}
}
script>
post
<script>
//创建异步对象
var xhr = new XMLHttpRequest();
//设置请求基本信息,并加上请求头
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.open('post', 'test.php' );
//发送请求
xhr.send('name=Lan&age=18');
xhr.onreadystatechange = function () {
// 这步为判断服务器是否正确响应
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
script>
onreadystatechange
这个监听函数是来监听readyState这个状态值得:
状态值 | 描述 |
---|---|
0 | 请求还未初始化,还未调用open( ) |
1 | 请求已建立但未发送,还未调用send( ) |
2 | 接受原始响应数据,为解析做准备 |
3 | 正在解析数据,根据响应头部返回的MIME类型把数据转换成能通过responseText等形式存取的格式 |
4 | 响应完成,数据解析完成 |
优缺点 | 描述 |
---|---|
优点 | 局部更新 |
优点 | 原生支持,不需要任何插件 |
优点 | 原生支持,不需要任何插件 |
缺点 | 可能破坏浏览器后退功能 |
缺点 | 嵌套回调,难以处理 |
其实Jquery的ajax就是在原生的ajax的基础上进行了封装,其实没有太多好说的东西,不过加上了对JSONP
的支持,附上例子:
<script>
var loginBtn = document.getElementsByTagName("button")[0];
loginBtn.onclick = function(){
ajax({
type:"post",
url:"test.php",
data:"name=lan&pwd=123456",
success:function(data){
console.log(data);
}
});
}
script>
ajax方法里面需要传入一个对象参数,里面包括了一些常见的参数,其实jquery维护了这么多年了,ajax请求其实已经很方便了,如果非要说有什么缺点的话,就是依然对回调嵌套不方便,然后就是如果为了一个JqueryAjax就引入整个jquery,文件比较大,成本过高。
Fetch是ajax非常好的一个替代品,很有可能将来会完全代替ajax的地位。我们先来看下浏览器的支持情况:
我们可以看到IE浏览器完全不支持Fetch,并且移动端的很多浏览器也不支持Fetch,不过可以使用第三方的ployfill来获得支持。Github.fetch
不管是原生的Ajax还是Jquery封装的Ajax都有一个问题就在于回调地狱,fetch很友好的解决了这个问题,fetch大概长这个样子:
fetch(...).then(fun2)
.then(fun3)
.....
.catch(fun)
它给人一种同步的流程来书写非同步的操作,成功的解决了回调地狱的问题。Fetch能做到这一点,是因为Fetch API是基于Promise
设计的。并且fetch调用非常简单,因为它是挂在BOM上的,属于全局的方法。
我们使用Fetch来获取数据时,会返回给我们一个Pormise对象,我们简单看一下:
<script>
fetch("http://www.abc.cn/test")
.then(Response => {
console.log(Response);
})
script>
输出如下:
OK就是true,status是200,我们可以看到这里面并没有我们想要的数据,其实数据都在body属性里面,是一种数据流的形式,一般服务器会给我们返回JSON数据的格式,我们可以调用response.json来转化下数据:
<script>
fetch("http://www.abc.cn/test")
.then(Response => Response.json())
.then(data => {
console.log(data);
})
script>
处理之后,我们继续.then就可以拿到处理之后的数据了。所以这么来看的话通过Fetch来获取数据是非常简洁简单的。
Fetch发送数据也非常的简单,API长这样:
fetch(url,options)
第二个参数会传入一个对象来配置请求的信息。下面先看一个例子:
<script>
fetch('http://www.mozotech.cn/bangbang/index/user/login', {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams([["username", "Lan"],["password", "123456"]]).toString()
})
.then(res => {
console.log(res);
return res.text();
})
.then(data => {
console.log(data);
})
script>
对传入的参数做个说明:
参数名 | 描述 |
---|---|
method | 请求的方法,默认GET |
headers | 请求的头信息 |
body | 请求的内容主体 |
值得一提的是,fetch默认的post的header是Content-Type:text/plain;charset=UTF-8
,不过通常我们的post请求是通过表单的形式提交的。所以我们需要把header修改为:Content-Type:application/x-www-form-urlencoded
fetch发送请求时,不像XHR,因为它默认是不带上Cookie的,如果站点依赖于维护一个用户会话,可能导致未经认证的请求,所以我们需要手动的把Cookie带上,只需加上 credentials: 'include'
即可:
<script>
fetch('https://www.abc.com/search', {
method: 'GET',
credentials: 'include' // 强制加入Cookie
})
.then((res)=>{
return res.text()
})
.then((res)=>{
console.log(res)
})
script>
优缺点 | 描述 |
---|---|
优点 | 解决回调地狱 |
优点 | 使用起来更加简洁 |
缺点 | API 偏底层,需要封装 |
缺点 | 默认不带Cookie,需要手动添加 |
缺点 | 浏览器支持情况不是很友好,需要第三方的ployfill |
Vue2.0之后,axios开始受到更多的欢迎了。其实axios也是对原生XHR的一种封装,不过是Promise实现版本。
它是一个用于浏览器和 nodejs 的 HTTP 客户端,符合最新的ES规范。简单看下如何使用即可
<script>
axios({
method: 'post',
url: '/abc/login',
data: {
userName: 'Lan',
password: '123'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
script>
感觉axios算是比较完美的一种方案了,几乎没有什么大的缺点。
其实有这么多种的请求方法和解决方案,总结一下:原生XHR几乎很少开发会用,JqueryAjax属于老当益壮的那种,虽然很老,但是很好用,Fetch是属于初生牛犊,还需要慢慢成长,axios就目前来说,算是非常好的了,无脑使用即可。