Ajax与Axios

一、概述

1.1 浏览器发送的请求类型

1.1.1 同步请求

同步请求的特点:

  • 按照代码顺序依次发起;
    • 一个请求未得到响应时,后续请求会被阻塞。

同步发起方式

  • 在地址栏输入URL:同步的get请求。
  • 的ref:同步的get请求。
  • 带有src:同步的get请求。
  • :同步的get|post请求。

1.1.2 异步请求

发起方式:

  • js代码发起

发起异步请求的工具:

  • XmlHttpRequest对象。

异步请求的特点:

  • 创建一个新线程发起请求,获取响应;
    • 在等待响应期间:主线程正常向下执行。

1.2 Ajax的作用

异步请求,局部刷新,适用单页富应用场景

二、XmlHttpRequest对象

2.1 XmlHttpRequest作用

发起异步请求,接收响应

2.2 XmlHttpRequest使用步骤

第一步: 创建对象

  • let xhr= new XmlHttpRequest();

第二步:初始化该对象:设置监听

  • 设置获取成功响应的回调函数

  • 设置失败响应的回调函数

  • 代码实现

    xhr.onreadystatechange = function (){
        if(xhr.readyState==4&&xhr.status==200)
        {
    				// 调用成功后的回调函数
            document.getElementById("shwRslt").innerText = xhr.responseText;
        }
    		else if(xhr.readyState==4&&xhr.status !==200)
    		{
    				// 调用失败响应回调函数
    		}
    }
    

第三步:

  • 代码实现:

    xhr.open(method, url, async)

  • 说明:

    • method:指定具体的请求方式
    • url: 接口url;
    • async:指定请求是否为异步执行;false:同步,true: 异步

第四步:(依据请求方式可选)设置请求头

  • 代码实现:

    xhr.setRequestHeader(“Content-Type”, value);

  • 选择依据:

    • get|delete不需要
    • post|put 需要

第五步:发起请求

  • 代码实现:
    • xhr.send([parmas]);
  • 说明:
    • params: 指的放在请求体中的参数;
    • 只有在post|put可能被使用;

2.3 实现示例

(function()
{
    var MyAjax=function (){};
    MyAjax.prototype={
        myMtdRqst:function (mth,url,paramer,masync,disposeRslt)
        {
            const xhr = newXMLHttpRequest();
            xhr.onreadystatechange=function ()
            {
                if(xhr.readyState == 4)
                {
                    if(xhr.status == 200)
                    {
                        disposeRslt(xhr.responseText);
                    }
                }
            }
            if(mth=="GET")
            {
                url= `${url}?name=${paramer}`;
                paramer=null;
            }
            xhr.open(mth,url,masync);
            if(mth=="POST")
            {
                xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
                paramer=`name=${paramer}`;
            }
            xhr.send(paramer);
        }
    }
    window.myajax=new MyAjax();
})();

三、Ajax

3.1 概述

3.1.1什么是Ajax?

Ajax是对原生XHR的封装,为了达到我们跨越的目的,增添了对JsonP的支持。

异步的javascript和xml,ajax不是一门新技术,而是多种技术的组合,用于快速的创建动态页面,能够实现无刷新更新数据从而提高用户体验。
  属性:url、method、dataType、beforeSend、success、error…

3.1.2Ajax原理?

由客户端请求ajax引擎,再由ajax引擎请求服务器,服务器作出一系列响应之后返回给ajax引擎,由ajax引擎决定将这个结果写入到客户端的什么位置。实现页面无刷新更新数据。

3.1.3核心对象

XMLHttpRequest

3.2 使用

3.2.1 前置条件

4.3 Axios的使用

4.3.1 使用Axios配置发起请求

axios({
//指定的请求方式
method: 'get',
//指定服务器处理请求的URL
url: '',
//指定客户端向服务器发送数据的格式: application/json
headers: {contentType: ""},
//用于指定get|delect请求携带的参数
params: {},
//指定post|put请求携带的参数
data: {},
}).then(res=>{})//成功后的回调函数
.catch(res=>{})//失败后的回调函数

4.3.执行get请求的两种方式

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

4.4 Axios发送POST|PUT请求

4.4.1 application/json 、 application/x-www-form-urlencoded和multipart/form-data区别

  • application/json
    • 消息主体是序列化后的 JSON 字符串。
  • application/x-www-form-urlencoded
    • 表示使用URL编码的方式来编码表单, 是浏览器默认的编码格式。
    • 格式为: username=twm&email=good@qq.com
  • multipart/form-data
    • 表示表单上传的是文件。

4.4.2 默认情况下的POST|PUT请求

4.4.2.1 默认情况下请求配置

  • Content-Type: application/json
  • 参数将会被自动转换成json字符串

4.4.1.2

4.4.3 修改POST|PUT请求配置,提交原生Form表单格式的参数

4.4.3.1 实现要点:

当修改Content-Type为application/x-www-form-urlencoded时:

  • 无其它操作时:Axios会自动将URL编码转换成json串。
    • 如下所示:

      {
      	"name":"启用","type":"1","alias":"enable","roleId":"1","features":"依据权限启用指定的被禁用的菜单","path":"","componentName":"",
      	"componentAlias":"菜单管理","iconClass":"fas fa-redo-alt","parentId":"3",
      	"routerParentId":"1","createdDate":null,"createdUser":"admin","modifiedDate":null,"modifiedUser":"","enabled":true,"permission":"sys:menu:enable"
      }
      
    • 此时后端将无法正确获取数据。

      • 使用@RequestBody描述参数时:将抛出如下异常: HttpMediaTypeNotSupportedException ,具体信息为:
        • org.springframework.web.HttpMediaTypeNotSupportedException: Content type ‘application/x-www-form-urlencoded;charset=UTF-8’ not supported
      • 不使用该注解描述参数时:不会抛出异常,但所有字段值都为 null。
  • 后端正确解析参数的方法
    • 思路:需要对Axios自动换成的Json进行还原成URL编码格式。

    • 方式一:配置POST|PUT请求,自定义转换方法。根据官网介绍,可以通过如下配置:

      	// `transformRequest` 允许在向服务器发送前,修改请求数据
        // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
        // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
        transformRequest: [function (data, headers) {
          // 对 data 进行任意转换处理
          return data;
        }],
      
    • 方式二:通过 qs 第三方模块,完成配置。具体实现步骤:

      • 第一步:引用qs。axios模块默认整合了qs模块,仅需通过import导入即可。

        import Qs from "qs";
        
      • 第二步:调用Qs.Stringify()方法,实参为待转换的数据对象。

        const {data} = await that.$http.post("/menu", Qs.stringify(that.menuData), {headers: {"Content-Type" : "application/x-www-form-urlencoded"}});
        
      • 转换后结果为:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-na0aEA39-1653130782778)(Ajax%E4%B8%8EAxios%206c512/Untitled.png)]

      • 此时,后端不需要使用@RequestBody注解描述实参,就能够正常解析并接收提交的数据。
      • 该方法同样适用于POST|PUT请求提交单值参数。实现方式一致。

4.5 Axios的拦截器

4.5.1 概述

4.5.1.1 作用

  • 常用于对Axios在请求或响应被 thencatch 处理前拦截,提前做出必要的处理。

4.5.1.2 分类

  • 请求拦截器:axios.interceptors.request.use()
  • 响应拦截器:axios.interceptors.response.use()

4.5.1.3 注意事项

  • 使用拦截器提前处理后,一定要返回处理的形参。

4.5.2 请求拦截器

4.5.2.1 拦截器原型

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

4.5.2.2 具体适用场景示例

  1. 在前后端分离项目中,对于用户每次请求做token认证
axios.interceptors.request.use(config => {
  if(sessionStorage.getItem("tokenContent"))
  {
    let tokenContent = JSON.parse(sessionStorage.getItem("tokenContent"));
    if(tokenContent.tokeHead && tokenContent.tokenBody) {
      if (tokenContent.tokenHeader)
        config.headers[tokenContent.tokenHeader] = tokenContent.tokenHead + tokenContent.tokenBody;
      else
        config.headers.Authorization = tokenContent.tokenHead + tokenContent.tokenBody;
    }
  }
  return config;
})

4.5.3 响应拦截器

4.5.3.1 拦截器原型

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

4.5.3.2 适用场景

  1. 对业务逻辑执行失败的失败响应统一处理
axios.interceptors.response.use(response => {
  let code = [2000, 5001, 5002, 5003];
  if(!code.includes(response.data.operateStatusCode))
  {
    Notification.error(response.data.operateMessage);
  }
  return response;
})

五、Ajax与Axios返回结果区别

Ajax:未对返回结果进行封装:结果保存在成功|失败的回调的形参中。

Axios:结果进行了封装:promise对象

axios是通过Promise实现对ajax技术的一种封装,就像jquery对ajax的封装一样。

简单来说就是ajax技术实现了局部数据的刷新,axios实现了对ajax的封装,axios有的ajax都有,ajax有的axios不一定有。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐