前端网络哀求之JavaScript XHR、Fetch、Axios

[复制链接]
发表于 2026-2-5 01:51:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一、JavaScript XHR、Fetch

AJAX:一种在无需重新加载整个网页的环境下,可以或许更新部分网页的技能。在配景与服务器举行少量数据交换,Ajax 可以使网页实现异步更新。在不重新加载整个网页的环境下,对网页的某部分举行更新
Fetch:基于 promise 计划的。Fetch 的代码布局比起 ajax 简单多。fetch 不是 ajax 的进一步封装,而是原生 js,没有使用 XMLHttpRequest 对象
1.1 前端数据哀求方式


  • 后端:服务器
  • 服务器端渲染 SSR(后端渲染):全部都是后端开辟的

    • 客户端发送哀求
    • 服务端吸收哀求并使用 jsp/asp/php 返回相应 HTML 文档
    • 页面革新,客户端加载新的HTML文档

  • SSR 的缺点

    • 页面本质上只有一些数据发生了变革,而服务器却要重绘整个页面,违背了 DRY(Don’t repeat yourself)原则
    • 给网络带宽带来不须要的开销

  • 前后端分离(客户端渲染、前端渲染)

    • 后端只必要关心 API 服务器(提供数据的服务器)和数据库
    • AJAX:

      • 在不重新革新网页的环境下与服务器通讯,交换数据,或更新页面(无页面革新获取服务器数据的技能)
      • 吸收并使用从服务器发来的数据
      • 异步的 JavaScript 和 XML(不消了,现在使用 Json)


1.2 HTTP


  • 超文本传输协议:用于分布式、协作式和超媒体信息体系的应用层协议
  • 最早是为了吸收 html 页面,欣赏器举行渲染
  • http 是一个客户端和服务端之间哀求和相应的尺度
  • 通过 HPPT 大概 HTTPS( http上增长的一个安全层)协议哀求的资源由同一资源标识符 URL 来标识

    • 通过使用网页欣赏器、网络爬虫大概别的的工具,客户端发起一个HTTP哀求到服务器上指定端口(默认端口为80)

      • 这个客户端为用户署理步调(user agent)

    • 相应的服务器上存储着一些资源,好比 HTML文件和图像

      • 这个相应服务器为源服务器(origin server)


  • http 就是和服务器沟通的一种协议:哀求对象、相应对象
  • 网页中的资源通常是被放在 web 资源服务器中,由欣赏器主动发送 http 哀求来获取、剖析、展示的
1.3 网页中资源的获取


  • 网页中的资源通常是被放在 Web 资源服务器中,由欣赏器主动发送 HTTP 哀求来获取、剖析、展示的
  • **页面中许多数据是动态展示的:**页面中的数据展示、搜刮数据、表单验证等等,也是通过在 JavaScript 中发送 HTTP 哀求获取的
1.4 HTTP 的构成


  • 一次 http 哀求重要包罗:哀求和相应
  • 哀求

    • 哀求行:方法(哀求方式)、URL、协议版本(现在采取的是什么版本
    • 哀求头:客户端会默认转达过来一些信息

      • content-type:哀求携带的数据范例(告诉服务器现在传送的数据以什么情势传已往)

        • application/x-www-form-urlencoded:以&分隔的键值对(以=分隔)
        • application/json:{“”:“”}json范例
        • text/plain:平凡文本 ×
        • application/xml:少用,xml范例
        1. <xml>
        2.     <name>lili</name>
        3. </xml>
        复制代码

        • multipart/form-data:上传文件,许多时间不必要手动设置

      • content-length:文件的巨细长度
      • keep-alive:不立刻断开,继承保持毗连一会儿

        • node 开辟服务器:保持五秒
        • http1.1 默认开启了

      • acept-encoding(吸收的客户端):告知服务器,客户端支持吸收的文件的压缩格式

        • zip/rar/7z
        • gzip(给你返回更小的压缩文件)

      • accept:我(客户端)可以或许吸收的文件格式(一样寻常为 json)
      • user-agent:客户端相干的信息


  • 相应

    • 相应行:协议版本、状态码、状态码的缘故起因短语

      • 200 OK 哀求乐成
      • 201 Created POST哀求,创建新的资源
      • 301 哀求资源的URL已经修改,重定向
      • 大于四百:错误
      • 400 客户端的错误
      • 401 未授权的错误
      • 403 客户端没有权限访问
      • 404 服务器找不到哀求的资源
      • 500 服务器错误,服务器不知道怎样处置惩罚
      • 503 服务器不可用

    • 相应头

      • 拿到相应数据:xhr.response
      • 可以设置吸收的范例:xhr.responseType="json"默认是text

    • 相应体

1.5 HTTP 的版本


  • HTTP/0.9 版本:1991年,只支持 get 哀求方法获取文本数据
  • HTTP/1.0:TCP毗连
  • HTTP/1.1(使用最广泛)

    • 发布于1997年
    • 增长了PUT、DELETE等哀求方法
    • 采取长期毗连(Connection: keep-alive),多个哀求可以共用同一个 TCP 毗连

  • HTTP/2.0
  • HTTP/3.0
1.6 HTTP 的哀求方式


  • 发送一次哀求怎样同服务器举行沟通
  • RFC(版本规范)中界说了一组哀求方式,标识要对给定资源实验的操纵

    • GET:哀求数据,获取数据
    • HEAD:返回的数据没有相应体
    • POST:提交数据
    • PUT:更换目标资源
    • DELETE:删除数据
    • PATCH:修改数据
    • CONNECT:署理服务器
    • TRACE:消息环回测试

1.7 AJAX 发送哀求


  • 第一种方式

    • 创建 XMLHttpRequest 对象
    • 监听状态的改变(宏使命)

      • 一次网络哀求中状态发生了许多次变革,数字表近况态

        • 0(不监听):署理被创建
        • 1 (open):open 方法已经被调用
        • 2(send):send 方法已经被调用,而且头部和状态已经可得到
        • 3(下载中)
        • 4:DONE 已完成

      • 这个状态并非是 HTTP 的相应状态,而是记载的 XMLHttpRequest 对象的状态变革:http 相应状态通过 status 获取
      • **发送同步哀求:**将 open 的第三个参数设置为 false

        • 发送哀求(欣赏器资助发送对应的哀求):现实开辟使用异步哀求,不会壅闭js代码继承实验: xhr.open("get", "http://123.207.32.32:8000/home/multidata", false)


    • 除了 onreadystatechange 另有其他的事故可以监听

      • loadstart:哀求开始
      • progress:文件上传
      • abort:取消了哀求
      • load:哀求乐成完成
      • loadend
      • error:发生毗连错误
      • onload:只调用一次
      • timeout:哀求超时

    • 设置哀求

      • open方法来设置,参数如下:
      • method:哀求的方式
      • URL:哀求的所在

        • json 范例的接口(90%)
        • text 范例的接口
        • xml 范例的接口


    1.     // 1.
    2.     const xhr = new XMLHttpRequest()
    3.     // 2.onload监听数据加载完成
    4.     xhr.onload = function() {
    5.       // const resJSON = JSON.parse(xhr.response)
    6.       console.log(xhr.response)
    7.       // console.log(xhr.responseText)
    8.       // console.log(xhr.responseXML)
    9.     }
    10.     // 3.告知xhr获取到的数据的类型
    11.     xhr.responseType = "json"
    12.     // xhr.responseType = "xml"
    13.     // 4.配置网络请求
    14.     // 4.1.json类型的接口
    15.     xhr.open("get", "http://xxxxx")
    16.     // 4.2.json类型的接口
    17.     // xhr.open("get", "http://xxxxx/hello_json")
    18.     // 4.3.text类型的接口
    19.     // xhr.open("get", "http://xxxxx/hello_text")
    20.     // 4.4.xml类型的接口
    21.     // xhr.open("get", "xxxxx/hello_xml")
    22.     // 5.发送网络请求
    23.     xhr.send()
    复制代码
  1. <script>
  2.     // xhr四步骤:
  3.     // 1. 创建XMLHttpRequest对象
  4.     // 所有的东西都放在了 xhr 里面
  5.     const xhr = new XMLHttpRequest()
  6.     // 2. 监听状态的改变(宏任务)
  7.     xhr.onreadystatechange=function(){
  8.       if(xhr.readyState!==XMLHttpRequest.DONE)return
  9.       // 2.1将字符串转成JSON对象
  10.       // const resJSON=JSON.parse(xhr.response)
  11.       // const banners=resJSON.data.banner
  12.       log(xhr.response)
  13.     }
  14.   // 告知xhr获取到的数据的类型,默认设置为text
  15.       xhr.responseType="json"
  16.     // 3. 调用open方法进行配置
  17.     //open第三个参数boolean表示同步或者异步,默认true异步
  18.     xhr.open("get","https://www.baidu.com",false)
  19.   
  20.     // 4. 调用send发送请求
  21.     xhr.send()
  22.       </script>
复制代码
1.8 获取 http 的状态码


  • 前面都是记载 xhr 对象本身的状态变革,并非针对 http 的网络哀求状态,http 网络哀求的状态必要通过 .status 获取
  1.     // 1.创建对象
  2.     const xhr = new XMLHttpRequest()
  3.     // 2.监听结果
  4.     xhr.onload = function() {
  5.       console.log(xhr.status, xhr.statusText)
  6.       // 根据http的状态码判断是否请求成功
  7.       if (xhr.status >= 200 && xhr.status < 300) {
  8.         console.log(xhr.response)
  9.       } else {
  10.         console.log(xhr.status, xhr.statusText)
  11.       }
  12.     }
  13.     xhr.onerror = function() {
  14.       console.log("onerror", xhr.status, xhr.statusText)
  15.     }
  16.     // 3.设置响应类型
  17.     xhr.responseType = "json"
  18.     // 4.配置网络请求
  19.     // xhr.open("get", "http://xxxxx/abc/cba/aaa")
  20.     xhr.open("get", "http://xxxxx/home/multidata")
  21.     // 5.发送网络请求
  22.     xhr.send()
复制代码
1.9 Get、Post 哀求传参


  • 要不要转达数据取决于接口需不必要数据
  • url

    • 主机所在
    • 服务器端标语
    • 路径

  • 常见的转达给服务器数据的方式有如下几种:

    • 方式一:GET 哀求的 query 参数

      • 缺点:以明文的情势直接放在对应的 URL,属于 URL 的一部分,没有那么安全;而 post 哀求转达参数的方式有许多种

        • 放在哀求体内里,FormData 是默认格式


    • 方式二:POST 哀求  x-www-form-urlencoded 格式
    • 方式三:POST 哀求  FormData 格式
    • 方式四:POST 哀求 JSON 格式

  1.    const formEl = document.querySelector(".info")
  2.     const sendBtn = document.querySelector(".send")
  3.     sendBtn.onclick = function() {
  4.       // 创建xhr对象
  5.       const xhr = new XMLHttpRequest()
  6.       // 监听数据响应
  7.       xhr.onload = function() {
  8.         console.log(xhr.response)
  9.       }
  10.       // 配置请求
  11.       xhr.responseType = "json"
  12.       // 1.传递参数方式一: get -> query
  13.       // xhr.open("get", "http://xxxx/get?name=lili&age=18&address=广州市")
  14.       // 2.传递参数方式二: post -> urlencoded
  15.       // xhr.open("post", "http://xxxx/posturl")
  16.       // // 发送请求(请求体body)
  17.       // xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
  18.       // xhr.send("name=lili&age=18&address=广州市")
  19.       // 3.传递参数方式三: post -> formdata
  20.       // xhr.open("post", "http://xxxx/postform")
  21.       // 得将元素转成 form 对象
  22.       // // formElement对象转成FormData对象
  23.       // const formData = new FormData(formEl)
  24.       // xhr.send(formData)
  25.       // 4.传递参数方式四: post -> json
  26.       xhr.open("post", "http://xxx/postjson")
  27.       xhr.setRequestHeader("Content-type", "application/json")
  28.       xhr.send(JSON.stringify({name: "lili", age: 18, height: 1.88}))
  29.     }
  30.    
复制代码
1.10 ajax 网络哀求封装
  1.     function liliajax({
  2.       url,
  3.       method = "get",
  4.       data = {},
  5.       headers = {}, // token
  6.       success,
  7.       failure
  8.     } = {}) {
  9.       // 1.创建对象
  10.       const xhr = new XMLHttpRequest()
  11.       // 2.监听数据
  12.       xhr.onload = function() {
  13.         if (xhr.status >= 200 && xhr.status < 300) {
  14.           success && success(xhr.response)
  15.         } else {
  16.           failure && failure({ status: xhr.status, message: xhr.statusText })
  17.         }
  18.       }
  19.       // 3.设置类型
  20.       xhr.responseType = "json"
  21.       // 4.open方法
  22.       // 一般不推荐写在 data 里面
  23.       if (method.toUpperCase() === "GET") {
  24.         // 对 data 进行遍历
  25.         const queryStrings = []
  26.         for (const key in data) {
  27.           queryStrings.push(`${key}=${data[key]}`)
  28.         }
  29.         url = url + "?" + queryStrings.join("&")
  30.         xhr.open(method, url)
  31.         xhr.send()
  32.       } else {
  33.         xhr.open(method, url)
  34.         xhr.setRequestHeader("Content-type", "application/json")
  35.         xhr.send(JSON.stringify(data))
  36.       }
  37.       return xhr
  38.     }
  39.     // 调用者
  40.     liliajax({
  41.       url: "http://xxx/get",
  42.       method: "GET",
  43.       data: {
  44.         name: "lili",
  45.         age: 18
  46.       },
  47.       success: function(res) {
  48.         console.log("res:", res)
  49.       },
  50.       failure: function(err) {
  51.         // alert(err.message)
  52.       }
  53.     })
  54.     // liliajax({
  55.     //   url: "http://xxxx/postjson",
  56.     //   method: "post",
  57.     //   data: {
  58.     //     name: "jsondata",
  59.     //     age: 22
  60.     //   },
  61.     //   success: function(res) {
  62.     //     console.log("res:", res)
  63.     //   },
  64.     //   failure: function(err) {
  65.     //     // alert(err.message)
  66.     //   }
  67.     // })
复制代码
  1. function liliajax({
  2.   url,
  3.   method = "get",
  4.   data = {},
  5.   timeout = 10000,
  6.   headers = {}, // token
  7. } = {}) {
  8.   // 1.创建对象
  9.   const xhr = new XMLHttpRequest()
  10.   // 2.创建Promise
  11.   const promise = new Promise((resolve, reject) => {
  12.     // 2.监听数据
  13.     xhr.onload = function() {
  14.       if (xhr.status >= 200 && xhr.status < 300) {
  15.         resolve(xhr.response)
  16.       } else {
  17.         reject({ status: xhr.status, message: xhr.statusText })
  18.       }
  19.     }
  20.     // 3.设置类型
  21.     xhr.responseType = "json"
  22.     xhr.timeout = timeout
  23.     // 4.open方法
  24.     if (method.toUpperCase() === "GET") {
  25.       const queryStrings = []
  26.       for (const key in data) {
  27.         queryStrings.push(`${key}=${data[key]}`)
  28.       }
  29.       url = url + "?" + queryStrings.join("&")
  30.       xhr.open(method, url)
  31.       xhr.send()
  32.     } else {
  33.       xhr.open(method, url)
  34.       xhr.setRequestHeader("Content-type", "application/json")
  35.       xhr.send(JSON.stringify(data))
  36.     }
  37.   })
  38.   promise.xhr = xhr
  39.   return promise
  40. }
复制代码
  1.     const promise = liliajax({
  2.       url: "http://xxxx/get",
  3.       data: {
  4.         username: "lili",
  5.         password: "123456"
  6.       }
  7.     })
  8.     promise.then(res => {
  9.       console.log("res:", res)
  10.     }).catch(err => {
  11.       console.log("err:", err)
  12.     })
复制代码
1.11 timeout、手动取消哀求


  • timeout 欣赏器到达逾期时间还没有获取对应的结果,取消本次哀求
  • 可以通过 abort 方法欺压取消哀求
  1.   <button>取消请求</button>
  2.   <script>
  3.     const xhr = new XMLHttpRequest()
  4.     xhr.onload = function() {
  5.       console.log(xhr.response)
  6.     }
  7.     xhr.onabort = function() {
  8.       console.log("请求被取消掉了")
  9.     }
  10.    
  11.     xhr.responseType = "json"
  12.     // 1.超市时间的设置
  13.     xhr.ontimeout = function() {
  14.       console.log("请求过期: timeout")
  15.     }
  16.     // timeout: 浏览器达到过期时间还没有获取到对应的结果时, 取消本次请求
  17.     // xhr.timeout = 3000
  18.     xhr.open("get", "http://xxxxx/timeout")
  19.     xhr.send()
  20.     // 2.手动取消结果
  21.     const cancelBtn = document.querySelector("button")
  22.     cancelBtn.onclick = function() {
  23.       xhr.abort()
  24.     }
  25.   </script>
复制代码
1.12 熟悉 Fetch 和 Fetch API 发送网络哀求


  • fetch 是 xhr 的代替方案,提供了更加今世的处置惩罚方案
  • 返回值是一个 Promise

    • 在哀求发送乐成时,调用 resolve 回调 then
    • 在哀求发送失败时,调用 reject 回调 catch

  • 全部的操纵并不是都在一个对象上面
  • fetch 函数的使用

    • 参数

      • input

        • 界说要获取的资源所在,可以是一个 URL 字符串,也可以使用一个 Request 对象(实验性特性)范例

      • init:其他初始化参数

        • method: 哀求使用的方法,如 GET、POST
        • headers: 哀求的头信息
        • body: 哀求的 body 信息



  1.     // 1.fetch发送get请求
  2.     // 1.1.未优化的代码
  3.     // fetch("xxxx").then(res => {
  4.     //   // 1.获取到response
  5.     //   const response = res
  6.     //   // 2.获取具体的结果
  7.     //   response.json().then(res => {
  8.     //     console.log("res:", res)
  9.     //   })
  10.     // }).catch(err => {
  11.     //   console.log("err:", err)
  12.     // })
  13.     // 1.2. 优化方式一:
  14.     // fetch("xxxx").then(res => {
  15.     //   // 1.获取到response
  16.     //   const response = res
  17.     //   // 2.获取具体的结果
  18.     //   return response.json()
  19.     // }).then(res => {
  20.     //   console.log("res:", res)
  21.     // }).catch(err => {
  22.     //   console.log("err:", err)
  23.     // })
  24.     // 1.3. 优化方式二:
  25.     // async function getData() {
  26.     //   const response = await fetch("http://xxxxx")
  27.     //   const res = await response.json()
  28.     //   console.log("res:", res)
  29.     // }
  30.     // getData()
  31.     // 2.post请求并且有参数
  32.     async function getData() {
  33.       // const response = await fetch("http://xxxxx/postjson", {
  34.       //   method: "post",
  35.       //   // headers: {
  36.       //   //   "Content-type": "application/json"
  37.       //   // },
  38.       //   body: JSON.stringify({
  39.       //     name: "lili",
  40.       //     age: 18
  41.       //   })
  42.       // })
  43.       
  44.       const formData = new FormData()
  45.       formData.append("name", "lili")
  46.       formData.append("age", 18)
  47.       const response = await fetch("http://xxxx/postform", {
  48.         method: "post",
  49.         body: formData
  50.       })
  51.       // 获取response状态
  52.       console.log(response.ok, response.status, response.statusText)
  53.       const res = await response.json()
  54.       console.log("res:", res)
  55.     }
  56.     getData()
复制代码
1.13 XMLHttpRequest 文件上传


  • 文件上传:头像上传、照片等
  • 通过表单传给服务器
  • 可以检察上传的进度
  1. <input class="file" type="file">
  2.   <button class="upload">上传文件</button>
  3.   
  4.   <script>
  5.     // xhr/fetch
  6.     const uploadBtn = document.querySelector(".upload")
  7.     uploadBtn.onclick = function() {
  8.       // 1.创建对象
  9.       const xhr = new XMLHttpRequest()
  10.       // 2.监听结果
  11.       xhr.onload = function() {
  12.         console.log(xhr.response)
  13.       }
  14.       xhr.onprogress = function(event) {
  15.         console.log(event)
  16.       }
  17.       
  18.       xhr.responseType = "json"
  19.       xhr.open("post", "http://xxxxx/upload")
  20.       // 表单
  21.       const fileEl = document.querySelector(".file")
  22.       const file = fileEl.files[0]
  23.       const formData = new FormData()
  24.       formData.append("avatar", file)
  25.       xhr.send(formData)
  26.     }
  27.   </script>
复制代码
1.14 Fetch 哀求文件上传
  1. <input class="file" type="file">
  2.   <button class="upload">上传文件</button>
  3.   
  4.   <script>
  5.     // xhr/fetch
  6.     const uploadBtn = document.querySelector(".upload")
  7.     uploadBtn.onclick = async function() {
  8.       // 表单
  9.       const fileEl = document.querySelector(".file")
  10.       const file = fileEl.files[0]
  11.       const formData = new FormData()
  12.       formData.append("avatar", file)
  13.       // 发送fetch请求
  14.       const response = await fetch("http://xxxx/upload", {
  15.         method: "post",
  16.         body: formData
  17.       })
  18.       const res = await response.json()
  19.       console.log("res:", res)
  20.     }
  21.   </script>
复制代码
二、网络哀求库 - axios

Axios:是一种基于 Promise 封装的 HTTP 客户端。
特点如下:

  • 欣赏器端发起 XMLHttpRequests 哀求
  • node 端发起 http 哀求
  • 支持 Promise API
  • 监听哀求和返回
  • 对哀求和返回举行转化
  • 取消哀求
  • 主动转换 json 数据
  • 客户端支持反抗 XSRF 攻击
2.1 axios


  • 功能特点

    • 在欣赏器中发送 XMLHttpRequests 哀求
    • 在 node.js 中发送 http 哀求
    • 支持 Promise API

      • fetch 也支持 promise

    • 拦截哀求和相应
    • 转换哀求和相应数据

  • axios: ajax i/o system
2.2 常见设置选项


  • 哀求所在:url: ‘/user’,
  • 哀求范例:method: ‘get’,
  • 请根路径:baseURL: ‘http://www.xxx.com/api’,
  • 哀求前的数据处置惩罚:transformRequest:[function(data){}],
  • 哀求后的数据处置惩罚:transformResponse: [function(data){}],
  • 自界说的哀求头:headers:{‘x-Requested-With’:‘XMLHttpRequest’},

    • 由服务器决定

  • URL查询对象:params:{ id: 12 },
  • 查询对象序列化函数:paramsSerializer: function(params){ }
  • request body:data: { key: ‘aa’},
  • 超时设置:timeout: 1000,
  1. import { createApp } from "vue";
  2. import App from "./App.vue";
  3. import axios from "axios";
  4. createApp(App).mount("#app");
  5. // 1. baseURL
  6. const baseURL = "http://xxxxx:8000"
  7. // 给axios实例配置公共的基础配置
  8. axios.defaults.baseURL = baseURL
  9. axios.defaults.baseURL = 10000
  10. axios.defaults.headers = {}
  11. // 1.1 get:
  12. axios.get("/home/multidata").then(res => {
  13.   console.log(res.data);
  14. })
  15. // 1.2 get
复制代码
2.3 axios 哀求方式


  • 支持多种哀求方式

    • axios(config)
    • axios.request(config)
    • axios.get(url[, config])

      • 可以或许直接在欣赏器中敲回车发送的哀求

    • axios.delete(url[, config])
    • axios.head(url[, config])
    • axios.post(url[, data[, config]])
    • axios.put(url[, data[, config]])
    • axios.patch(url[, data[, config]])

  1. import { createApp } from "vue";
  2. import App from "./App.vue";
  3. import axios from "axios";
  4. createApp(App).mount("#app");
  5. //1. 发送 request请求:发送一些配置
  6. axios
  7.   .request({
  8.     url: "http://xxxxx",
  9.     method: "get",
  10.   })
  11.   .then((res) => {
  12.     console.log(res.data);
  13.   });
  14. // 2. 发送get请求:
  15. // 传递参数:
  16. // 2.1 querry参数
  17. axios.get("http:/xxxxx/lyric?id=500665346", {}).then((res) => {
  18.   console.log(res.data);
  19. });
  20. // 2.2 params这个使用比较多
  21. axios
  22.   .get("http://xxxxx/lyric", {
  23.     params: {
  24.       id: 500665346,
  25.     },
  26.   })
  27.   .then((res) => {
  28.     console.log(res.data);
  29.   });
  30. // 3. 发送 post 请求:post请求的 url 参数是不能拼接到后面的,只能放在请求体里面
  31. // 两种写法
  32. axios
  33.   .post("http://xxxxx/postjson", {
  34.     username: "lili",
  35.     password: "123455",
  36.   })
  37.   .then((res) => {
  38.     console.log(res.data);
  39.   });
  40. axios
  41.   .post("http://xxxxx/postjson", {
  42.     data: {
  43.       username: "lili",
  44.       password: "123455",
  45.     },
  46.   })
  47.   .then((res) => {
  48.     console.log(res.data);
  49.   });
复制代码

  • 同时发送两个哀求

    • 使用 axios.all, 可以放入多个哀求的数组
    • axios.all([]) 返回的结果是一个数组,使用 axios.spread 可将数组 [res1,res2] 睁开为 res1, res2

  1. // 2. axios 发送多个请求
  2. // Promise.all
  3. axios.all([
  4.   axios.get("/xxx/multidata"),
  5.   axios.get("/xxx/multidata2")
  6. ]).then(res => {
  7.   console.log(res.data);
  8. })
复制代码
2.4 axios 创建实例


  • 对于单独的 url 会创建单独的实例
  • 看开辟过程中有多少个实例
  1. import { createApp } from "vue";
  2. import App from "./App.vue";
  3. import axios from "axios";
  4. createApp(App).mount("#app");
  5. // axios 默认库提供给我们的实例对象
  6. axios.get("http://xxxxx/lyric?id=500665346");
  7. // 创建其他的实例发送网络请求
  8. const instance1 = axios.create({
  9.   baseURL: "http://xxxx",
  10.   timeout: 6000,
  11.   headers: {},
  12. });
  13. instance1.get("/lyric", {
  14.   params: {
  15.     id: 500665346,
  16.   },
  17. });
  18. const instance2 = axios.create({
  19.   baseURL: "http://xxxxx",
  20.   timeout: 9000,
  21.   headers: {},
  22. });
复制代码
2.5 哀求和相应拦截器


  • 在发出网络哀求之前

    • 哀求乐成

      • 表现 loading 动画
      • 对原来的设置文件举行修改

        • header
        • 认证登岸:传入 token、cookie
        • 对哀求参数举行某些转化



  • 在得到相应结果之前

    • 相应乐成

      • 竣事 loading 动画
      • 对数据举行转化,再返回数据


  • 举行处置惩罚
  1. // 对实例配置拦截器
  2. axios.interceptors.request.use(请求成功回调拦截, 请求失败回调拦截);
  3. // 一般都不会请求失败
  4. axios.interceptors.request.use(
  5.   (config) => {
  6.     if (config.url === "user/info") config.headers["token"] = "lili";
  7.     // 请求成功的拦截
  8.     return config;
  9.   },
  10.   (err) => {
  11.     console.log("请求失败的拦截,基本上不会发生");
  12.   }
  13. );
  14. // 400 404 请求失败
  15. axios.interceptors.response.use(成功回调, 失败回调);
  16. axios.interceptors.response.use(
  17.   (res) => {
  18.     // 这里对响应的结果进行转化
  19.     // 在得到结果的时候就不需要 res.data 了
  20.     // 响应成功的拦截
  21.     return res.data;
  22.   },
  23.   (err) => {
  24.     // 响应失败的拦截
  25.     return err;
  26.   }
  27. );
  28. axios
  29.   .get("http://xxxxx/lyric?id=500665346")
  30.   .then((res) => {
  31.     console.log(res);
  32.   })
  33.   .catch((err) => {
  34.     console.log(err);
  35.   });
复制代码
2.6 封装
  1. import axios from "axios";
  2. class LiliRequest {
  3.   constructor(baseURL, timeout = 10000) {
  4.     // 创建一个实例进行配置
  5.     this.instance = axios.create({
  6.       baseURL,
  7.       timeout
  8.     })
  9.   }
  10.   request(config) {
  11.     return new Promise((resolve, reject) => {
  12.       this.instance
  13.         .request(config)
  14.         .then((res) => {
  15.           resolve(res.data);
  16.         })
  17.         .catch((err) => {
  18.           reject(err);
  19.         });
  20.     });
  21.   }
  22.   get(config) {
  23.     return this.request({ ...config, method: "get" });
  24.   }
  25.   post(config) {
  26.     return this.request({ ...config, method: "post" });
  27.   }
  28. }
  29. const liliRequest1 = new LiliRequest("http://www.baidu.com")
  30. const liliRequest2 = new LiliRequest("http://www.taobao.com")
  31. export default new LiliRequest()
复制代码
  1. import liliRequest from './service/index'
复制代码
三、TypeScript - axios 封装

3.1 根本封装
  1. import axios from "axios";
  2. import type { AxiosInstance, AxiosRequestConfig } from "axios";
  3. class LiliRequest {
  4.     instance: AxiosInstance;
  5.     // 1. 创建实例
  6.   // request 实例 => axios实例
  7.   constructor(config: AxiosRequestConfig) {
  8.     this.instance = axios.create(config);
  9.     }
  10.    
  11.     // 2. 封装网络请求的方法
  12.     request(config: AxiosRequestConfig) {
  13.        return this.instance.request(config)
  14.      }
  15.     get() { }
  16.    
  17. }
  18. export default LiliRequest;
复制代码
拦截器


  • 全局拦截
  1. import axios from "axios";
  2. import type { AxiosInstance, AxiosRequestConfig } from "axios";
  3. // 拦截器:蒙版 loading/token/修改配置
  4. class LiliRequest {
  5.   instance: AxiosInstance;
  6.   // 1. 创建实例
  7.   // request 实例 => axios实例
  8.   constructor(config: AxiosRequestConfig) {
  9.     this.instance = axios.create(config);
  10.     // 每个instance实例都添加拦截器
  11.     // 传入一个config对config进行修改再返回
  12.     this.instance.interceptors.request.use(
  13.       (config) => {
  14.         //  loading/token
  15.         console.log("全局请求成功的拦截");
  16.         return config;
  17.       },
  18.       (err) => {
  19.         console.log("全局请求失败的拦截");
  20.         return err;
  21.       }
  22.     );
  23.     this.instance.interceptors.response.use(
  24.       (res) => {
  25.         console.log("全局响应成功的拦截");
  26.         return res;
  27.       },
  28.       (err) => {
  29.         console.log("全局响应失败的拦截");
  30.         return err;
  31.       }
  32.     );
  33.   }
  34.   // 2. 封装网络请求的方法
  35.   request(config: AxiosRequestConfig) {
  36.     return this.instance.request(config);
  37.   }
  38.   get() {}
  39. }
  40. export default LiliRequest;
复制代码

  • 针对特定的哀求做拦截器
  1. import axios from "axios";
  2. import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from "axios";
  3. // 拦截器:蒙版 loading/token/修改配置
  4. import type { LILIInterceptors, LiliRequestConfig } from "./type";
  5. class LiliRequest {
  6.   instance: AxiosInstance;
  7.   // 1. 创建实例
  8.   // request 实例 => axios实例
  9.   constructor(config: LiliRequestConfig) {
  10.     this.instance = axios.create(config);
  11.     // 每个instance实例都添加拦截器
  12.     // 传入一个config对config进行修改再返回
  13.     this.instance.interceptors.request.use(
  14.       (config) => {
  15.         //  loading/token
  16.         console.log("全局请求成功的拦截");
  17.         return config;
  18.       },
  19.       (err) => {
  20.         console.log("全局请求失败的拦截");
  21.         return err;
  22.       }
  23.     );
  24.     this.instance.interceptors.response.use(
  25.       (res) => {
  26.         console.log("全局响应成功的拦截");
  27.         return res;
  28.       },
  29.       (err) => {
  30.         console.log("全局响应失败的拦截");
  31.         return err;
  32.       }
  33.     );
  34.     // 同时存在不存在覆盖
  35.     // 判断请求是否添加拦截器,针对每一个请求做精细化处理
  36.     // 针对特定的liliRequest实例添加拦截器
  37.     // if (config.interceptors) {//类型缩小
  38.     this.instance.interceptors.request.use(config.interceptors?.requestSuccessFn, config.interceptors?.requestFailureFn);
  39.     this.instance.interceptors.response.use(config.interceptors?.responseSuccessFn, config.interceptors?.responseFailureFn);
  40.     // }
  41.   }
  42.   // 2. 封装网络请求的方法
  43.   request(config: AxiosRequestConfig) {
  44.     return this.instance.request(config);
  45.   }
  46.   get() {}
  47. }
  48. export default LiliRequest;
复制代码

  • LiliRequest 类单次哀求:针对差异的需求创建差异的拦截
  1. import axios from "axios";
  2. import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from "axios";
  3. // 拦截器:蒙版 loading/token/修改配置
  4. import type { LILIInterceptors, LiliRequestConfig } from "./type";
  5. class LiliRequest {
  6.   instance: AxiosInstance;
  7.   // 1. 创建实例
  8.   // request 实例 => axios实例
  9.   constructor(config: LiliRequestConfig) {
  10.     this.instance = axios.create(config);
  11.     // 每个instance实例都添加拦截器
  12.     // 传入一个config对config进行修改再返回
  13.     this.instance.interceptors.request.use(
  14.       (config) => {
  15.         //  loading/token
  16.         console.log("全局请求成功的拦截");
  17.         return config;
  18.       },
  19.       (err) => {
  20.         console.log("全局请求失败的拦截");
  21.         return err;
  22.       }
  23.     );
  24.     this.instance.interceptors.response.use(
  25.       (res) => {
  26.         console.log("全局响应成功的拦截");
  27.         return res;
  28.       },
  29.       (err) => {
  30.         console.log("全局响应失败的拦截");
  31.         return err;
  32.       }
  33.     );
  34.     // 同时存在不存在覆盖
  35.     // 判断请求是否添加拦截器,针对每一个请求做精细化处理
  36.     // 针对特定的liliRequest实例添加拦截器
  37.     // if (config.interceptors) {//类型缩小
  38.     this.instance.interceptors.request.use(config.interceptors?.requestSuccessFn, config.interceptors?.requestFailureFn);
  39.     this.instance.interceptors.response.use(config.interceptors?.responseSuccessFn, config.interceptors?.responseFailureFn);
  40.     // }
  41.   }
  42.   // 2. 封装网络请求的方法
  43.   request(config: LiliRequestConfig) {
  44.     // 拦截器的本质是一些钩子函数,对其进行回调
  45.     if (config.interceptors?.requestSuccessFn) {
  46.       config = config.interceptors.requestSuccessFn(config);
  47.     }
  48.     return new Promise((resolve, reject) => {
  49.       this.instance
  50.         .request(config)
  51.         .then((res) => {
  52.           if (config.interceptors?.responseSuccessFn) {
  53.             res = config.interceptors.responseSuccessFn(res);
  54.           }
  55.           resolve(res);
  56.         })
  57.         .catch((err) => {
  58.           reject(err);
  59.         });
  60.     });
  61.   }
  62.   get() {}
  63. }
  64. export default LiliRequest;
复制代码
3.2 返回结果的范例处置惩罚


  • 返回结果是一个 unknown 范例
  • 网络哀求
  1. import liliRequest from "..";
  2. interface IHmoeData{
  3.   data: any,
  4.   returnCode: string,
  5.   success:boolean
  6. }
  7. liliRequest.request<IHmoeData>({
  8.   url:"/user/name"
  9. }).then(res => {
  10.   console.log(res);
  11.   
  12. })
复制代码

  • 封装类
  1. // 2. 封装网络请求的方法
  2.   request<T=any>(config: LiliRequestConfig) {
  3.     // 拦截器的本质是一些钩子函数,对其进行回调
  4.     if (config.interceptors?.requestSuccessFn) {
  5.       config = config.interceptors.requestSuccessFn(config);
  6.     }
  7.     return new Promise<T>((resolve, reject) => {
  8.       this.instance
  9.         .request<any,T>(config)
  10.         .then((res) => {
  11.           if (config.interceptors?.responseSuccessFn) {
  12.             // res = config.interceptors.responseSuccessFn(res);
  13.           }
  14.           resolve(res);
  15.         })
  16.         .catch((err) => {
  17.           reject(err);
  18.         });
  19.     });
  20.   }
复制代码
3.3 接口范例中的泛型处置惩罚


  • 封装类
  1. import axios from "axios";
  2. import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from "axios";
  3. // 拦截器:蒙版 loading/token/修改配置
  4. import type { LILIInterceptors, LiliRequestConfig } from "./type";
  5. class LiliRequest {
  6.   instance: AxiosInstance;
  7.   // 1. 创建实例
  8.   // request 实例 => axios实例
  9.   constructor(config: LiliRequestConfig) {
  10.     this.instance = axios.create(config);
  11.     // 每个instance实例都添加拦截器
  12.     // 传入一个config对config进行修改再返回
  13.     this.instance.interceptors.request.use(
  14.       (config) => {
  15.         //  loading/token
  16.         console.log("全局请求成功的拦截");
  17.         return config;
  18.       },
  19.       (err) => {
  20.         console.log("全局请求失败的拦截");
  21.         return err;
  22.       }
  23.     );
  24.     this.instance.interceptors.response.use(
  25.       (res) => {
  26.         console.log("全局响应成功的拦截");
  27.         return res.data;
  28.       },
  29.       (err) => {
  30.         console.log("全局响应失败的拦截");
  31.         return err;
  32.       }
  33.     );
  34.     // 同时存在不存在覆盖
  35.     // 判断请求是否添加拦截器,针对每一个请求做精细化处理
  36.     // 针对特定的liliRequest实例添加拦截器
  37.     // if (config.interceptors) {//类型缩小
  38.     this.instance.interceptors.request.use(config.interceptors?.requestSuccessFn, config.interceptors?.requestFailureFn);
  39.     this.instance.interceptors.response.use(config.interceptors?.responseSuccessFn, config.interceptors?.responseFailureFn);
  40.     // }
  41.   }
  42.   // 2. 封装网络请求的方法
  43.   request<T=any>(config: LiliRequestConfig<T>) {
  44.     // 拦截器的本质是一些钩子函数,对其进行回调
  45.     if (config.interceptors?.requestSuccessFn) {
  46.       config = config.interceptors.requestSuccessFn(config);
  47.     }
  48.     return new Promise<T>((resolve, reject) => {
  49.       this.instance
  50.         .request<any,T>(config)
  51.         .then((res) => {
  52.           if (config.interceptors?.responseSuccessFn) {
  53.             // res = config.interceptors.responseSuccessFn(res);
  54.           }
  55.           resolve(res);
  56.         })
  57.         .catch((err) => {
  58.           reject(err);
  59.         });
  60.     });
  61.   }
  62.   get() {}
  63. }
  64. export default LiliRequest;
复制代码

  • 修改范例
  1. import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from "axios";
  2. // 针对AxiosRequestConfig配置进行扩展
  3. export interface LILIInterceptors<T=AxiosResponse> {
  4.   requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig;
  5.   requestFailureFn?: (err: any) => any;
  6.   responseSuccessFn?: (res: T) => T;
  7.   responseFailureFn?: (err: any) => any;
  8. }
  9. export interface LiliRequestConfig<T=AxiosResponse> extends AxiosRequestConfig {
  10.   interceptors?: LILIInterceptors<T>;
  11. }
复制代码
3.4 添加其他哀求方式
  1.   get<T = any>(config: LiliRequestConfig<T>) {
  2.     return this.request({...config,method:"GET"})
  3.   }
  4.   post<T = any>(config: LiliRequestConfig<T>) {
  5.     return this.request({...config,method:"POST"})
  6.   }
  7.   delete<T = any>(config: LiliRequestConfig<T>) {
  8.     return this.request({...config,method:"DELETE"})
  9.   }
  10.   patch<T = any>(config: LiliRequestConfig<T>) {
  11.     return this.request({...config,method:"PATCH"})
  12.   }
复制代码
3.5 总结


  • 拦截器举行风雅控制

    • 全局拦截器
    • 实例拦截器
    • 单次哀求拦截器

  • 相应结果的范例处置惩罚

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表