浅析ajax和axios的使用和区别

135 阅读5分钟

------------------------前端小白,仅用作自我总结,有问题感谢指出------------------------

一、ajax

1. ajax概念

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

2. ajax跨域

2.1 跨域

浏览器不能执行其他网站的脚本,从一个域名的网页去请求另一个域名的资源时。域名、端口、协议任一不同,都是跨域。跨域是由浏览器的同源策略造成的,是浏览器施加的安全限制。

2.2 跨域解决办法

1.运维同学在服务器做设置

比如:在淘宝的服务器上设置:京东的域名在安全域名的白名单中。

2.前端开启Proxy本地代理

本地的ajax请求先请求到本地同域的服务器中,本地服务器中转请求到跨域服务器,ajax返回的数据也是先返回到本地服务器,由本地服务器再返回到浏览器端。

跨域的问题只只出现浏览器发送请求,服务器发送请求没有跨域问题。

    devServer: {
        proxy: {
            '/api': {
                target: 'http://cf-pc-dev.com:7777',
                changeOrigin: true, 
                pathRewrite: {
                    '^/api': '',
                },
            },
        },
    },

/api/users的请求会将请求代理到http://cf-pc-dev.com

changeOrigin 选项用于修改请求头中的 Host 字段,将其设置为目标URL的主机名

pathRewrite 选项用于重写请求路径,将 /api 去掉

3.jsonp的形式

浏览器端有一个函数名字叫aa,ajax返回的数据我们获取不到但是却可以操作(执行)。 浏览器如果返回123我们获取不到。 但是如果浏览器返回 aa()本地是可以正常执行的。 如果服务器返回 aa(123),也是可以执行的,结果是调用了本地的函数aa,此时如果函数能执行,那么123作为函数的参数被我们获取了。 这种形式就叫做jsonp,要完成这样的工作, 首先我们在发送请求时,需要告诉跨域的服务器,接收参数的函数名称是什么。 xhr.open('get','http://127.0.0.1/a.jsp?callback=aa') 其次,服务器的代码必须经过修改,能够将参数用名称包裹。

JSONP 只支持get请求、不支持post请求

3. 原生ajax

实现过程:

  1. 创建XMLHttpRequest对象
  2. 通过open()方法与服务器建立连接
  3. 通过send()方法发送数据给服务端
  4. 通过onreadystatechange事件监听服务器端的通信状态
  5. 接受服务端向客户端响应的数据结果
    // ajax传输的是文本且编码是utf-8编码
    
    const xhr = new XMLHttpRequest();  
  
    xhr.onreadystatechange = function () {  
      if (xhr.readyState == 4) {  
        if (xhr.status == 200) {  
          console.log(xhr.responseText)  
        } else {  
          alert('哎呀,服务器睡着啦');  
        }  
      }  
    }  
  
    xhr.open(method, url, true); // 创建HTTP请求,method请求类型,url地址,true表示异步  
    xhr.setRequestHeader(name, value); // name请求头部名称,value请求头部值
    xhr.send(); // 发送数据给服务

readyState4个状态:

0初始状态;1请求已发起;2服务器已回应;3数据已发送;4得到服务器的最终回应;

所以,onreadystatechange事件在一次请求中,会触发4次,我们只关心是否进入第四次

设置请求头:

设置发送数据的类型

Content-Type 指传输数据类型;

// 发送表单数据
GET方式,会将表单中的数据(键值对)经过urlencode编码后追加到url中。
POST方式,会将表单中的数据经过urlencode编码后放在request body中。
xhr.setRequestHeader('Content-Type''Application/x-www-form-urlencoded'); 

// 普通表单提交以及表单文件上传
xhr.setRequestHeader('Content-Type''multipart/form-data'); 

// 发送纯文本
xhr.setRequestHeader('Content-Type''text/plain');

4. ajax封装

    const ajax = {
    
      serialize: function (obj) {
        /*
        遍历对象obj,使用Object.entries方法将对象{a:1,b:2} 变为[['a',1],['b',2]]
        使用for of 遍历[['a',1],['b',2]]
        最终形成 'a=1&b=2'
        */
        let s = [];

        for (let item of Object.entries(obj)) {
          s.push(item.join('='))
        }

        s = s.join('&');
        return s;
      },
      
      get: function (url, data = {}) {
        return new Promise((resolve, reject) => {
          //创建xhr对象
          const xhr = new XMLHttpRequest();
          xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
              if (xhr.status === 200) {
                resolve(JSON.parse(xhr.response))
              } else {
                reject(xhr.status)
              }
            }
          }
          let param = this.serialize(data);
          param = param ? '?' + param : '';
          xhr.open('get', url + param, true);
          xhr.setRequestHeader('Content-Type', 'Application/x-www-form-urlencoded');
          xhr.send();
        })
      },
      
      post: function (url, data = {}) {
        return new Promise((resolve, reject) => {
          //创建xhr对象
          const xhr = new XMLHttpRequest();
          xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
              if (xhr.status === 200) {
                resolve(JSON.parse(xhr.response))
              } else {
                reject(xhr.status)
              }
            }
          }
          xhr.open('post', url, true);
          //设置请求头
          xhr.setRequestHeader('Content-Type', 'Application/x-www-form-urlencoded');
          xhr.send(this.serialize(data));
        })
      }
    };

    ajax.post('http://172.16.13.182/a', { a: 1, b: 2 }).then(function (result) {
      console.log(result);
    })

二、axios

2.1 定义

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中

2.2 特征

支持浏览器和node.js;返回promise对象;能拦截请求和响应;能转换JSON数据

2.3 接口请求写法

2.3.1 get请求

axios({  
    url'请求路径',  
    method'GET',  
    params: {},
}).then(res => {  
    console.log(res)
})

axios.get('请求路径', {  
    params: {  
        // 参数...  
    }  
}).then(res => {  
      console.log(res)
})

2.3.2 post请求

axios({  
    url'请求路径',  
    method'POST',  
    data: {},
}).then(res => {  
    console.log(res)
})

axios.post('请求路径', {  
    // 参数...
}).then(res => {  
      console.log(res)
})

2.4 axios拦截器

拦截器会在每次发起ajax请求和得到响应的时候自动触发。

应用场景:token身份验证

拦截器设置:1.建立interceptor.js文件,配置拦截器相关操作;2.在main.js引入

    // http request 拦截器
    axios.interceptors.request.use(
        config => {
            let token = sessionStorage.getItem('wti-manager-token');
            token = token ? '' + token : '';
            config.headers.Authorization = token;
            return config;
        },
        err => {
            return Promise.reject(err);
        }
    );

    // http response 拦截器
    axios.interceptors.response.use(
        response => {
            if (response.data.code === 401) {
                const elementMessage = Message;
                // 首先关掉之前所有的 message
                elementMessage.closeAll();
                elementMessage({
                    message: '登陆认证已过期,请重新登陆!',
                    type: 'warning',
                });
                Router.push({name: 'Login'});
            }
            return response.data;
        },
        error => {
            // console.log('reject', error);
            // 对响应错误做点什么
            window.top.postMessage(
                {
                    message: '您的网络连接失败,请稍后再试',
                    type: 'warning',
                    wti_type: 'message'
                },
                '*'
            );
            return Promise.reject(error.response.data);
        }
    );

ajax 与 axios 的根本区别

axios 是基于promise实现的对 ajax 技术的一种封装,两者用法基本一样,个别参数不同,axios 封装了一些更简便的 ajax 操作 axios 是 ajax,但是 ajax 不限于 axios