Ajax,Fetch,Axios请求的简单分析及对比

文章目录

  • 前言
  • 一、Ajax
    • 1.1、Ajax的get请求代码解析
    • 1.2、Ajax的post请求代码解析
    • 1.3、Ajax和Promise结合请求代码解析
    • 1.4、Ajax请求代码解析封装版(较完整)
  • 二、Fetch
    • 2.2、Fetch的请求代码解析
  • 三、Axios
    • 3.1、Axios的get请求代码解析
    • 3.2、Axios的post请求代码解析
  • 四、Axios和Ajax的区别
  • 五、Ajax,Fetch,Axios关系图及表格


前言

Ajax,Fetch,Axios网络请求的简单分析及对比,只是简单的对比,并不是很深入,希望可以帮助到你


一、Ajax

Ajax是异步的javascript和XML,Ajax不是一个技术,而是技术的统称,是一个概念模型,它包括了很多技术,并不是特指一个技术,它的重要特性就是实现页面的局部刷新,Ajax是一种思想,XMLHttpRequest只是实现Ajax的一种方式,面试中最容易面试到的就是手撕Ajax请求代码,下面展示三个Ajax不同情况下的代码,其实都大同小异,只是我分开写了而已

请求发送出去后,客户端需要接收服务器响应回来的数据,xhr对象中有一些属性,它们存储着服务端返回来的一些数据信息,如下表所示

Ajax,Fetch,Axios请求的简单分析及对比_第1张图片

1.1、Ajax的get请求代码解析

  function ajax(url) {
      //创建ajax对象(声明一个变量,用来实例化XMLHttpRequest对象)
      const xhr = new XMLHttpRequest();

      //使用ajax下的open方法打开接口,表示创建一个请求,
      // 参数分别是 get / post请求 接口地址 是否异步(true为异步请求,false为同步请求)
      xhr.open("get", url, false);

      // xhr对象可以绑定一个 onreadystatechange 事件,每当 readyState 属性发生改变,都会触发该事件,因此,该事件在一次请求中会被多次触发
      xhr.onreadystatechange = function () {
        // 判断是否已接收所有响应
        // readyState码:0:请求未初始化;1:服务连接已建立; 2:请求已接收; 3:请求处理中;4:请求已完成,切响应已就绪。
        if (xhr.readyState === 4) {
          //  //status状态码:2XX:成功处理请求;3XXX:需要重新定向,浏览器直接跳转;4XXX:客户端请求错误;5XXX:服务端错误
          if (xhr.status === 200) {
            // 从服务器端返回文本。
            console.log(xhr.responseText);
          }
        }
      };

      // 用send方法发送请求,send() 方法接收一个参数
      // 光调用了 open() 方法还不够,它只是创建了一个请求,但还没有发送请求,因此我们还要调用xhr对象上的另一个方法,即 send() 方法,表示将请求发送给目标URL
      //如果上面创建的是get请求,因此send()方法无需传参或者写null
      xhr.send();
    }
  // 调用
    ajax("这里写接口地址的链接");

1.2、Ajax的post请求代码解析

   function ajax(url) {
      //创建ajax对象(声明一个变量,用来实例化XMLHttpRequest对象)
      const xhr = new XMLHttpRequest();

      //使用ajax下的open方法打开接口,表示创建一个请求,
      // 参数分别是 get / post请求 接口地址 是否异步(true为异步请求,false为同步请求)
      xhr.open("post", url, false);
     //post方法必需,设置请求头
      xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
      // xhr对象可以绑定一个 onreadystatechange 事件,每当 readyState 属性发生改变,都会触发该事件,因此,该事件在一次请求中会被多次触发
      xhr.onreadystatechange = function () {
        // 判断是否已接收所有响应
        // readyState码:0:请求未初始化;1:服务连接已建立; 2:请求已接收; 3:请求处理中;4:请求已完成,切响应已就绪。
        if (xhr.readyState === 4) {
          //  //status状态码:2XX:成功处理请求;3XXX:需要重新定向,浏览器直接跳转;4XXX:客户端请求错误;5XXX:服务端错误
          if (xhr.status === 200) {
            // 从服务器端返回文本。
            console.log(xhr.responseText);
          }
        }
      };

      const postData = {
        userName: "小明",
        passWord: "123456",
      };
      // 用send方法发送请求,send() 方法接收一个参数
      // 光调用了 open() 方法还不够,它只是创建了一个请求,但还没有发送请求,因此我们还要调用xhr对象上的另一个方法,即 send() 方法,表示将请求发送给目标URL
      //如果上面创建的是get请求,因此send()方法无需传参
      //发送请求,把对象参数用JSON方法转为字符串参数
      xhr.send(JSON.stringify(postData));
    }
 // 调用
    ajax("这里写接口地址的链接");

1.3、Ajax和Promise结合请求代码解析

  function ajax(url) {
      const p = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", url, false);
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
            // 这里的 status 可以适当修改
            if (xhr.status === 200) {
              resolve(
                // 将得到 responseText 转换为JSON格式数据
                JSON.parse(xhr.responseText)
              );
            } else if (xhr.status === 404) {
              reject(new Error("404 not found"));
            }
          }
        };
        xhr.send(null);
      });
      return p;
    }

//调用
 // 调用
    ajax("这里写接口地址的链接")
      .then((res) => console.log(res))
      .catch((err) => console.err(err));

1.4、Ajax请求代码解析封装版(较完整)

   function ajax(option) {
        const p = new Promise((resolve, reject) => {
            // 这个方法主要是将对象形式的参数变成用&符号链接的字符串,方便传参使用
            // 例如 let obj={a:100,b:200} 通过该方法可以变成 a=100&b=100
            function objTostring(obj) {
                // 先判断参数是不是对象
                if (Object.prototype.toString.call(obj) === '[object Object]') {
                    let arr = [];
                    for (let i in obj) {
                        arr.push(i + '=' + obj[i])
                    }
                    return arr.join('&')
                } else {
                    throw new Error('参数应该是对象')
                }
            }

            const xhr = new XMLHttpRequest();
            //1、 配置请求方式
            option.type = option.type || 'get';//兼容,如果option中的type有值就用option中的,没有就用get
            //2、配置接口地址,不可以省略
            if (!option.url) {
                throw new Error('接口地址不能为空')
            }
            //  3、配置数据格式(get请求在地址栏拼接  post请求设置请求头)
            // 判断参数是否存在+get请求
            if (option.data && option.type === 'get') {
                option.url += '?' + objTostring(option.data)
            }
            //4、判断是否异步
            if (option.async === 'false' || option === false) {
                option.async = false//同步
            } else {
                option.async = true//异步
            }
            xhr.open(option.type, option.url, option.async);
            // 判断参数是否存在+post请求
            if (option.data && option.type === 'post') {
                // 配置请求头,post请求必须写请求头
                xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                // post请求进行传参(send传参)
                xhr.send(objTostring(option.data))
            } else {
                xhr.send();
            }
            // 5、同步异步获取数据
            if (option.async) {//option.async存在就是异步
                xhr.onload = function () {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        console.log('异步', xhr.responseText)

                        option.success && typeof option.success === 'function' && resolve(option.success(xhr.responseText))
                    } else {
                        option.error && typeof option.error === 'function' && reject(option.error('状态码有误!'))
                    }
                }
            } else {
                // 同步
                console.log('同步', xhr.responseText)
            }
        })
    }

 // ajax调用
    ajax({
        type: 'get',//可省略不写, 默认get,可设置成post
        url: 'https://www.fastmock.site/mock/33b2c932b3482797c85219d76a110350/api/home/echarts1',//不可省略
        data: {//传的参数,没有的话可省略不写

        },
        async: true,//可省略不写,默认为异步(true),可设置成同步(false)或者'false'
        success: function (res) {//获取数据成功后的回调函数
            // 我们在这里获取到数据后就可以进行页面的数据渲染了
            console.log('success', res)
        },
        error: function (err) {//获取数据失败后的回调函数
            throw new Error(err)
        }
    })

二、Fetch

Fetch是ES6出现的,它使用了ES6提出的Promise对象,是XMLHttpRequest的替代品,Fetch是一个原生的API,是真实存在的,是基于Promise实现的(链式调用)。
Fetch的特点:
使用Promis,不使用回调函数式(回调地域)
采用模块化设计,rep,res分开的,比较友好
网络性能更好

2.2、Fetch的请求代码解析

 function ajaxFetch(url) {
        fetch(url).then(res => res.json()).then(data => {
        console.log(data)
        })
        ajaxFetch(url)
      }

三、Axios

Axios是随着Vue的兴起被广泛使用的,目前来说,绝大多数的Vue项目中的网络请求都是利用Axios发起的,他并不是一个思想或者原生的API,而是一个封装库,Axios是基于Promise封装的网络请求库,是基于XHR的二次封装,可以用在浏览器和 node.js 中。
Axios的特点:
支持Promise的APi
自动转换json数据
使用时需要引入axios
axios可以用在浏览器和 node.js 中是因为,它会自动判断当前环境是什么,如果是浏览器,就会基于XMLHttpRequests实现axios。如果是node.js环境,就会基于node内置核心模块http实现axios

简单来说,axios的基本原理是:
1、axios还是属于 XMLHttpRequest, 因此需要实现一个ajax。或者基于http 。
2、还需要一个promise对象来对结果进行处理。

这里只展示请求,关于拦截器可看axios官网

3.1、Axios的get请求代码解析

// 方式一  将参数直接写在url中
axios.get('/geturl?id=12345')
.then((res) => {
  console.log(res)
})
.catch((err) => {
  console.log(err)
})
// 第二种方式  将参数直接写在params中
axios.get('/geturl', {
  params: {
    id: 12345
  }
})
.then((res) => {
  console.log(res)
})
.catch((err) => {
  console.log(err)
})

3.2、Axios的post请求代码解析

axios.post('/geturl', {
  id: 12345//注意!这里和get请求传参的第二种方式很像,但是不一样,需要仔细看
})
.then((res) => {
  console.log(res)
})
.catch((err) => {
  console.log(err)
})

四、Axios和Ajax的区别

axios是通过Promise实现对ajax技术的一种封装,axios比ajax更好用更安全。
简单来说就是ajax技术实现了局部数据的刷新,axios实现了对ajax的封装;总结就是axios是ajax,ajax不止axios。

五、Ajax,Fetch,Axios关系图及表格

Ajax,Fetch,Axios请求的简单分析及对比_第2张图片

请求方式 特点
Ajax 是一种技术统称,主要通过XHR实现网络请求
Fetch 是一个具体的API,基于Promise实现网络请求
Axios 是一个封装库,基于Promise对XHR封装

你可能感兴趣的:(ajax,javascript,前端)