Ajax、fetch、axios的区别与优缺点

背景

前端的技术发展速度非常的快,异步请求也是其重要的体现之一,从最早的原生XHR,再到JqueryAjax的统治时代,再到近来,fetch、axios等技术也开始出现并大量投入使用。

原生Ajax

Ajax是指一种创建交互式网页应用的网页开发技术,并且可以做到无需重新加载整个网页的情况下,能够更新部分网页,也叫作局部更新。

XMLHttpRequest 对象

使用ajax发送请求是依靠于一个对象,叫XmlHttpRequest对象,通过这个对象我们可以从服务器获取到数据,然后再渲染到我们的页面上。现在几乎所有的浏览器都有这个对象,只有IE7以下的没有,而是通过ActiveXObject这个对象来创建的。XmlHttpRequest对象有一些常见的方法:

方法 描述
abort() 停止当前请求
getAllResponseHeaders() 把HTTP请求的所有响应首部作为键/值对返回
getResponseHeader(“header”) 返回指定首部的串值
open(method,url) 建立对服务器的调用,还有3个可选参数,是否异步、用户名、密码
send(content) 向服务器发送请求
abort() 停止当前请求
setRequestHeader(header, value) 把指定首部设置为所提供的值。

ajax使用步骤

1.创建XmlHttpRequest对象
2.调用open方法设置基本请求信息
3.设置发送的数据,发送请求
4.注册监听的回调函数
5.拿到返回值,对页面进行更新

ajax的get/post请求

其实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 响应完成,数据解析完成

ajax优缺点

优缺点 描述
优点 局部更新
优点 原生支持,不需要任何插件
优点 原生支持,不需要任何插件
缺点 可能破坏浏览器后退功能
缺点 嵌套回调,难以处理

JqueryAjax

其实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

Fetch是ajax非常好的一个替代品,很有可能将来会完全代替ajax的地位。我们先来看下浏览器的支持情况:

我们可以看到IE浏览器完全不支持Fetch,并且移动端的很多浏览器也不支持Fetch,不过可以使用第三方的ployfill来获得支持。Github.fetch

Fetch写法

不管是原生的Ajax还是Jquery封装的Ajax都有一个问题就在于回调地狱,fetch很友好的解决了这个问题,fetch大概长这个样子:

fetch(...).then(fun2)
          .then(fun3)
          .....
          .catch(fun)

它给人一种同步的流程来书写非同步的操作,成功的解决了回调地狱的问题。Fetch能做到这一点,是因为Fetch API是基于Promise设计的。并且fetch调用非常简单,因为它是挂在BOM上的,属于全局的方法。

Fetch获取数据

我们使用Fetch来获取数据时,会返回给我们一个Pormise对象,我们简单看一下:

    <script>
        fetch("http://www.abc.cn/test")
            .then(Response => {
                console.log(Response);
            })
    script>

输出如下:
Ajax、fetch、axios的区别与优缺点_第1张图片
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发送数据

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

Cookie传递

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>

Fetch优缺点

优缺点 描述
优点 解决回调地狱
优点 使用起来更加简洁
缺点 API 偏底层,需要封装
缺点 默认不带Cookie,需要手动添加
缺点 浏览器支持情况不是很友好,需要第三方的ployfill

Axios

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就目前来说,算是非常好的了,无脑使用即可。

你可能感兴趣的:(JavaScript)