• axios


    文章基于尚硅谷

    HTTP

    1. 前后台交互的基本过程

    在这里插入图片描述

     

    1. 前后应用从浏览器端向服务器发送HTTP请求(请求报文)
    2. 后台服务器接收到请求后, 调度服务器应用处理请求, 向浏览器端返回HTTP响应(响应报文)
    3. 浏览器端接收到响应, 解析显示响应体/调用监视回调

    HTTP请求报文

    请求行:

    请求方式/url
    常用请求方式get post delete put  

    POST /login

    多个请求头

    Host: www.baidu.com
    Cookie: BAIDUID=AD3B0FA706E; BIDUPSID=AD3B0FA706;
    Content-Type: application/x-www-form-urlencoded 或者application/json

    请求体

    username=tom&pwd=123   urlencoded
    {"username": "tom", "pwd": 123}   json

    HTTP 响应报文

    响应状态行:

    status

    statusText

    多个响应头

    Content-Type: text/html;charset=utf-8
    Set-Cookie: BD_CK_SAM=1;path=/

    响应体

    html 文本/json 文本/js/css/图片...

    post 请求体参数格式

    1.Content-Type: application/x-www-form-urlencoded;charset=utf-8
    用于键值对参数,参数的键值用=连接, 参数之间用&连接
    例如: name=%E5%B0%8F%E6%98%8E&age=12
    2.Content-Type: application/json;charset=utf-8
    用于 json 字符串参数
    例如: {"name": "%E5%B0%8F%E6%98%8E", "age": 12}
    3.Content-Type: multipart/form-data
    用于文件上传请求

     常见的响应状态码

    200    OK                     请求成功。一般用于GET与POST请求
    201 Created                已创建。成功请求并创建了新的资源
    401 Unauthorized           未授权/请求要求用户的身份认证
    404 Not Found              服务器无法根据客户端的请求找到资源
    500 Internal Server Error  服务器内部错误,无法完成请求

    不同类型的请求及其作用

    1. 1. GET: 从服务器端读取数据
    2. 2. POST: 向服务器端添加新数据
    3. 3. PUT: 更新服务器端已经数据
    4. 4. DELETE: 删除服务器端数据

    API 的分类

    REST API: restful (Representational State Transfer (资源)表现层状态转化)
    (1) 发送请求进行CRUD 哪个操作由请求方式来决定
    (2) 同一个请求路径可以进行多个操作
    (3) 请求方式会用到GET/POST/PUT/DELETE
    非REST API: restless
    (1) 请求方式不决定请求的CRUD 操作
    (2) 一个请求路径只对应一个操作
    (3) 一般只有GET/POST

    测试: 可以使用json-server快速搭建模拟的rest api 接口

    2.json-server使用

    npm install -g json-server

    目标根目录下创建数据库 json 文件:db.json

    1. {
    2. "posts": [
    3. { "id": 1, "title": "json-server", "author": "typicode" },
    4. { "id": 2, "title": "json-server2", "author": "typicode" }
    5. ],
    6. "comments": [
    7. { "id": 1, "body": "some comment", "postId": 1 }
    8. ],
    9. "profile": { "name": "typicode" }
    10. }

    启动服务器执行命令

     json-server --watch db.json

    3 xhr的理解和使用

    1. 使用 XMLHttpRequest (XHR) 对象可以与服务器交互 , 也就是发送 ajax 请求
    2. 前端可以获取到数据,而无需让整个的页面刷新。
    3. 这使得 Web 页面可以只更新页面的局部,而不影响用户的操作。

    区别一般 http 请求与 ajax 请求

    1. ajax 请求是一种特别的 http 请求
    2. 对服务器端来说 , 没有任何区别 , 区别在浏览器端
    3. 浏览器端发请求 : 只有 XHR fetch 发出的才是 ajax 请求 , 其它所有的都是
    ajax 请求
    4. 浏览器端接收到响应
    (1) 一般请求 : 浏览器一般会直接显示响应体数据 , 也就是我们常说的刷新 /
    跳转页面
    (2) ajax 请求 : 浏览器不会对界面进行任何更新操作 , 只是调用监视的回调
    函数并传入响应相关数据

    xhrAPI

    • 1. XMLHttpRequest(): 创建 XHR 对象的构造函数
    • 2. status: 响应状态码值, 比如 200, 404
    • 3. statusText: 响应状态文本
    • 4. readyState: 标识请求状态的只读属性
            0: 初始
            1: open()之后
            2: send()之后
            3: 请求中
            4: 请求完成
    • 5. onreadystatechange: 绑定 readyState 改变的监听
    • 6. responseType: 指定响应数据类型, 如果是'json', 得到响应后自动解析响应体数据
    • 7. response: 响应体数据, 类型取决于 responseType 的指定
    • 8. timeout: 指定请求超时时间, 默认为 0 代表没有限制
    • 9. ontimeout: 绑定超时的监听
    • 10. onerror: 绑定请求网络错误的监听
    • 11. open(): 初始化一个请求, 参数为: (method, url[, async])
    • 12. send(data): 发送请求
    • 13. abort(): 中断请求
    • 14. getResponseHeader(name): 获取指定名称的响应头值
    • 15. getAllResponseHeaders(): 获取所有响应头组成的字符串
    • 16. setRequestHeader(name, value): 设置请求头

    4 使用XHR 封装一个简单版axios

    axios特点

    • 函数的返回值为promise, 成功的结果为response, 失败的结果为error
    • 能处理多种类型的请求: GET/POST/PUT/DELETE
    • 函数的参数为一个配置对象
      1. {
      2. url: '', // 请求地址
      3. method: '', // 请求方式GET/POST/PUT/DELETE
      4. params: {}, // GET/DELETE 请求的 query 参数
      5. data: {}, // POST/PUT 请求的请求体参数
      6. }

    • 响应 json数据 自动解析为 js的对象/数组

     简单axios编码实现

    1. function axios({
    2. url,
    3. methed = 'GET',
    4. params = {},
    5. data = {}
    6. }) {
    7. //返回一个premise对象
    8. return new Promise((resolve, reject) => {
    9. // 执行异步Ajax请求
    10. //处理method(转为大写)
    11. methed = methed.toUpperCase()
    12. /*
    13. {
    14. id: 1,
    15. xxx:'abc'
    16. }
    17. */
    18. //处理query参数(拼接到url上) id=1&xxx=abc
    19. let queryString = ''
    20. Object.keys(params).forEach(key => {
    21. queryString += `${key}=${params[key]}&`
    22. })
    23. if (queryString) {//id=1&xxx=abc&
    24. //去除最后的&
    25. queryString = queryString.substring(0, queryString.length - 1)
    26. //拼接到url上
    27. url += '?' + queryString
    28. }
    29. //创建xhr对象
    30. const request = new XMLHttpRequest()
    31. //打开连接(初始化请求)
    32. request.open(methed, url, true)
    33. //绑定状态改变的监听
    34. request.onreadystatechange = function () {
    35. //如果请求没有完成,直接结束
    36. if (request.readyState !== 4) {
    37. return
    38. }
    39. //如果响应状态码在200到299之间代表成功 否则失败
    40. const { status, statusText } = request
    41. //如果请求成功调用resolve()
    42. if (status >= 200 & status <= 299) {
    43. //准备结果对象
    44. const response = {
    45. data: JSON.parse(request.response),//响应json数据自动解析为js的对象/数组
    46. status,
    47. statusText
    48. }
    49. resolve(response)
    50. } else {//如果请求失败调用reject()
    51. reject(new Error('request error status is ' + status))
    52. }
    53. }
    54. //发送请求
    55. if (methed === 'GET' || methed === 'DELETE') {
    56. request.send()
    57. } else if (methed === 'POST' || methed === 'PUT') {
    58. request.setRequestHeader('Content-Type', 'application/json;charset=utf-8')//告诉服务器请求体的格式是json
    59. request.send(JSON.stringify(data))//发送json格式请求体参数 send异步
    60. }
    61. })
    62. }

    使用测试

    1. // 1. GET请求:从服务器端获取数据
    2. function testGet() {
    3. axios({
    4. url: 'http://localhost:3000/posts',
    5. method: 'GET',
    6. params:{
    7. id: 1,
    8. xxx: 'abc'
    9. }
    10. }).then(
    11. response => {
    12. console.log(response)
    13. },
    14. error => {
    15. alert(error.message)
    16. }
    17. )
    18. }
    19. // 2. POST请求:向服务器端添加数据
    20. function testPost() {
    21. axios({
    22. url: 'http://localhost:3000/posts',
    23. method: 'POST',
    24. data: {
    25. "title": "json-server_post",
    26. "author": "typicode_post"
    27. }
    28. }).then(
    29. response => {
    30. console.log(response)
    31. },
    32. error => {
    33. alert(error.message)
    34. }
    35. )
    36. }
    37. // 3. PUT请求:服务器更新数据
    38. function testPut() {
    39. axios({
    40. url: 'http://localhost:3000/posts/1',
    41. method: 'PUT',
    42. data: {
    43. "title": "json-server_put",
    44. "author": "typicode_put"
    45. }
    46. }).then(
    47. response => {
    48. console.log(response)
    49. },
    50. error => {
    51. alert(error.message)
    52. }
    53. )
    54. }
    55. // 3. DELETE请求:服务器删除数据
    56. function testDelete() {
    57. axios({
    58. url: 'http://localhost:3000/posts/2',
    59. method: 'delete'
    60. }).then(
    61. response => {
    62. console.log(response)
    63. },
    64. error => {
    65. alert(error.message)
    66. }
    67. )
    68. }

    5 axios的理解和使用

    特点

    1. 基于promise的封装XHR的异步ajax请求库
    2. 浏览器端/node端都可以使用
    3. 支持请求/响应拦截器
    4. 支持请求取消
    5. 请求/响应数据转换
    6. 批量发送多个请求

    常用语法

    1. axios(config): 通用/最本质的发任意类型请求的方式
    2. axios(url[, config]): 可以只指定url发get请求
    3. axios.request(config): 等同于axios(config)
    4. axios.get(url[, config]): 发get请求
    5. axios.delete(url[, config]): 发delete请求
    6. axios.post(url[, data, config]): 发post请求
    7. axios.put(url[, data, config]): 发put请求
    8. axios.defaults.xxx: 请求的默认全局配置
    9. axios.interceptors.request.use(): 添加请求拦截器
    10. axios.interceptors.response.use(): 添加响应拦截器
    11. axios.create([config]): 创建一个新的axios(它没有下面的功能)
    12. axios.Cancel(): 用于创建取消请求的错误对象
    13. axios.CancelToken(): 用于创建取消请求的token对象
    14. axios.isCancel(): 是否是一个取消请求的错误
    15. axios.all(promises): 用于批量执行多个异步请求
    16. axios.spread(): 用来指定接收所有成功数据的回调函数的方法

    在这里插入图片描述

     难点语法的理解和使用

    axios.create(config)

    1. 根据指定配置创建一个新的 axios, 也就就每个新 axios 都有自己的配置
    2. axios 只是没有取消请求和批量发请求的方法 , 其它所有语法都是一致的
    3. 为什么要设计这个语法 ?
    (1) 需求 : 项目中有部分接口需要的配置与另一部分接口需要的配置不太一
    , 如何处理
    (2) 解决 : 创建 2 个新 axios, 每个都有自己特有的配置 , 分别应用到不同要
    求的接口请求中

    实例

     

    拦截器函数/ajax 请求/请求的回调函数的调用顺序

    1. 说明 : 调用 axios() 并不是立即发送 ajax 请求 , 而是需要经历一个较长的流程
    2. 流程 : 请求拦截器 2 => 请求拦截器 1 => ajax 请求 => 响应拦截器 1 =>
    应拦截器 2 => 请求的回调
    3. 注意 : 此流程是通过 promise 串连起来的 , 请求拦截器传递的是 config, 响应
    拦截器传递的是 response
    1. // 添加两个请求拦截器(回调函数)
    2. axios.interceptors.request.use(
    3. config => {
    4. console.log('request interceptor1 onResolved()') // -----------2
    5. return config
    6. },
    7. error => {
    8. console.log('request interceptor1 onRejected()')
    9. return Promise.reject(error)
    10. }
    11. )
    12. axios.interceptors.request.use(
    13. config => {
    14. console.log('request interceptor2 onResolved()') // -----------1
    15. return config
    16. },
    17. error => {
    18. console.log('request interceptor2 onRejected()')
    19. return Promise.reject(error)
    20. }
    21. )
    22. // 添加两个响应拦截器
    23. axios.interceptors.response.use(
    24. resopnse => {
    25. console.log('response interceptor1 onResolved()') // -----------3
    26. return resopnse
    27. },
    28. error => {
    29. console.log('response interceptor1 onRejected()')
    30. return Promise.reject(error)
    31. }
    32. )
    33. axios.interceptors.response.use(
    34. resopnse => {
    35. console.log('response interceptor2 onResolved()') // -----------4
    36. return resopnse
    37. },
    38. error => {
    39. console.log('response interceptor2 onRejected()')
    40. return Promise.reject(error)
    41. }
    42. )
    43. axios.get('http://localhost:3000/posts')
    44. .then(response => {
    45. console.log('data', response.data) //data Array(4) -------------5
    46. })
    47. .catch(error => {
    48. cosole.log('error', error.message)
    49. })
    50. // request interceptor2 onResolved()
    51. // request interceptor1 onResolved()
    52. // response interceptor1 onResolved()
    53. // response interceptor2 onResolved()
    54. // data Array(4)

    取消请求

    1. 基本流程
    配置 cancelToken 对象
    缓存用于取消请求的 cancel 函数
    在后面特定时机调用 cancel 函数取消请求
    在错误回调中判断如果 error cancel, 做相应处理
    2. 实现功能
    点击按钮 , 取消某个正在请求中的请求
    在请求一个接口前 , 取消前面一个未完成的请求
    server.js
    1. const express = require('express')
    2. const cors = require('cors')
    3. const app = express()
    4. // 使用cors, 允许跨域
    5. app.use(cors())
    6. // 能解析urlencode格式的post请求体参数
    7. app.use(express.urlencoded({ extended: false }))
    8. // 能解析json格式的请求体参数
    9. app.use(express.json())
    10. app.get('/products1', (req, res) => {
    11. setTimeout(() => {
    12. res.send([
    13. { id: 1, name: 'product1.1' },
    14. { id: 2, name: 'product1.2' },
    15. { id: 3, name: 'product1.3' }
    16. ])
    17. }, 1000 + Math.random() * 2000);
    18. })
    19. app.get('/products2', (req, res) => {
    20. setTimeout(() => {
    21. res.send([{
    22. id: 1,
    23. name: 'product2.1'
    24. },
    25. {
    26. id: 2,
    27. name: 'product2.2'
    28. },
    29. {
    30. id: 3,
    31. name: 'product2.3'
    32. }
    33. ])
    34. }, 1000 + Math.random() * 2000);
    35. })
    36. app.listen(4000, () => {
    37. console.log('server app start on port 4000')
    38. })
    1. // 添加请求拦截器
    2. axios.interceptors.request.use((config) => { // 只写一个成功的回调
    3. // 在准备发请求前,取消未完成的请求
    4. if (typeof cancel === 'function'){
    5. cancel('取消请求')
    6. }
    7. // 添加一个cancelToken的配置
    8. config.cancelToken = new axios.CancelToken(function executor(c){ // c是用于取消当前请求的函数
    9. // 保存取消函数,用于之后可能需要取消当前请求
    10. cancel = c;
    11. })
    12. return config
    13. })
    14. // 添加响应拦截器
    15. axios.interceptors.response.use(
    16. response => { // 成功的回调
    17. cancel = null
    18. return response
    19. },
    20. error => { // 失败的回调
    21. //在错误回调中判断如果 error 是 cancel, 做相应处理 解决上一次请求异步回调清空cancel的问题
    22. if (axios.isCancel(error)){ // 请求取消的错误
    23. console.log('请求取消的错误', error.message)
    24. // 中断promise链
    25. return new Promise(() => {})
    26. }else{ // 请求出错了
    27. cancel = null
    28. // 将错误向下传递
    29. // throw error
    30. return Promise.reject(error)
    31. }
    32. }
    33. )
    34. let cancel // 用于保存取消请求的函数
    35. function getProducts1() {
    36. axios({
    37. url: 'http://localhost:4000/products1'
    38. }).then(
    39. response => {
    40. console.log('请求1成功了', response.data)
    41. },
    42. error => { // 只用处理请求失败的情况,取消请求的错误不用处理
    43. console.log('请求1失败了', error.message, error)
    44. }
    45. )
    46. }
    47. function getProducts2() {
    48. axios({
    49. url: 'http://localhost:4000/products2'
    50. }).then(
    51. response => {
    52. console.log('请求2成功了', response.data)
    53. },
    54. error => {
    55. console.log('请求2失败了', error.message, error)
    56. }
    57. )
    58. }
    59. function cancelReq() {
    60. if (typeof cancel === 'function'){
    61. cancel('强制取消请求')
    62. } else {
    63. console.log('没有可取消的请求')
    64. }
    65. }

  • 相关阅读:
    Gradient Descent
    Java设计模式
    云计算到底什么,十个问答告诉您
    nodejs+vue 网上招聘系统elementui
    设计模式11、享元模式Flyweight
    java计算机毕业设计汽车美容管理(附源码、数据库)
    基于TMS320F28377D开发板的DSP CLA算法案例开发手册
    VSCode创建VUE前端项目
    C++ Reference: Standard C++ Library reference: Containers: list: list: cend
    如厕神器,阿里大神手打的Spring全家桶脑图(spring+MVC+Boot+Cloud)
  • 原文地址:https://blog.csdn.net/qq_60587956/article/details/126054966