axios笔记

axios函数的使用语法

   axios({
       url: '目标资源地址'
     }).then((result) => {
       // 对服务器返回的数据做后续处理
     })

查询参数

携带给服务器额外信息,让服务器返回我想要的某一部分数据而不是全部数据

查询参数的语法

在 url 网址后面用?拼接格式:http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值

参数名一般是后端规定的,值前端看情况传递即可

axios 如何携带查询参数?

   * 使用 params 选项即可

     axios({
       url: '目标资源地址',
       params: {
         参数名: 值
       }
     }).then(result => {
       // 对服务器返回的数据做后续处理
     })



  axios({
         url: 'http://hmajax.itheima.net/api/city',
         // 查询参数
         params: {
           pname: '辽宁省'
         }
       }).then(result => {
         console.log(result.data.list)
         document.querySelector('p').innerHTML = result.data.list.join('<br>')
       })

常用请求方法和数据提交

请求方法是一些固定单词的英文,例如:GET,POST,PUT,DELETE,PATCH(这些都是http协议规定的),每个单词对应一种对服务器资源要执行的操作

前面我们获取数据其实用的就是GET请求方法,但是axios内部设置了默认请求方法就是GET,我们就没有写

但是提交数据需要使用POST请求方法

  axios({
       url: 'http://hmajax.itheima.net/api/register',
       method: 'POST',
       data: {
         username: 'itheima007',
         password: '7654321'
       }
     })
   })

  axios({
       url: '目标资源地址',
       method: '请求方法',
       data: {
         参数名: 值
       }
     }).then(result => {
       // 对服务器返回的数据做后续处理
     })

GET


        axios.get("/data.json", {
          //带参数时  ————若无参数时直接省略params对象不写
          params: {
            id: 5,
          },
        })
        .then((result) => {
          // result不是直接的返回结果
          console.log("数据:", result);
          // result.data才是真正的返回结果
          console.log("真正的数据:", result.data);
        })
        .catch((err) => {
          console.log(err);
        });

   axios({
      method: "get",
      url: "/data.json"
    }).then((res) => {
      // result不是直接的返回结果
      console.log("数据:", result);
      // result.data才是真正的返回结果
      console.log("真正的数据:", result.data);
    });

POST

//发送post请求携带参数,直接使用"uname=dingding&upwd=123456"
    axios.post("/data.json", "uname=dingding&upwd=123456").then(res=>{
      console.log(res)
    });


 //发送post请求携带参数,这种传参方式后台得使用requestBody处理
    axios.post("/data.json", {uname:"dingding",upwd:123456}).then(res=>{
      console.log(res)
    });


  let data = {uname:"dingding",upwd:123456};
     axios({
       method:'post',
       url:'/data.json',
       // 与get请求使用params不同的是,post请求使用data属性
       data:data
     }).then(res=>{
       console.log(res)
    })

axios 错误处理

使用 axios 的 catch 方法,捕获这次请求响应的错误并做后续处理,语法如下:

axios({
     // ...请求选项
   }).then(result => {
     // 处理成功数据
   }).catch(error => {
     // 处理失败错误
   })

 axios({
         url: 'http://hmajax.itheima.net/api/register',
         method: 'post',
         data: {
           username: 'itheima007',
           password: '7654321'
         }
       }).then(result => {
         // 成功
         console.log(result)
       }).catch(error => {
         // 失败
         // 处理错误信息
         console.log(error)
         console.log(error.response.data.message)
         alert(error.response.data.message)
       })

axios实例的创建与配置

场景:如果后端接口地址有多个,并且超时时长不一样,此时我们可以我们可以创建axios实例,利用axios实例进行网络请求

 // 创建axios实例1
    let instance = axios.create({
      baseURL: "http://loacalhost:8080",
      timeout: 1000,
    });
    instance.get("/data.json").then((res) => {
      console.log(res);
    });
    // 创建axios实例2  ————倘若有两个域名或设置超时时长不一样,我们可以再创建一个axios实例
    let instance2 = axios.create({
      baseURL: "http://loacalhost:8081",
      timeout: 2000,
    });
    instance2.get("/city.json").then((res) => {
      console.log(res);
    });

axios实例的相关配置


let instance = axios.create({
  // 创建实例时设置配置默
  baseURL: "", //请求的域名/基本地址
  timeout: 2000, //请求的超时时长,单位毫秒,默认。
  url: "/data.json", //请求路径
  method: "get", //请求方法
  headers: {
    //设置请求头————我们可以给请求头添加一些参数
    token: "",
    post: {
       'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    }
  },
  params: { id: 5 }, //将请求参数拼接到url上
  data: { id: 5 }, //将请求参数放置到请求体里
});

xios全局配置

axios.defaults.baseURL = 'http://localhost:8080'
axios.defaults.timeout = 2000

拦截器

请求拦截器 ——在请求之前拦截请求

    // 添加请求拦截器
   /*需要拦截请求的原因
    *   1.config中包含了某些不符合服务器要求的信息
    *   2.发送网络请求的时候需要向用户展示一些加载中的图标
    *   3.网站需要登录才能请求资源,也就是需要token才能请求资源*/
    axios.interceptors.request.use(config => {
      // 在发送请求之前做些什么
      console.log(config)
      return config; //拦截器里一定要记得将拦截的结果处理后返回,否则无法进行数据获取
    }, err=>{
        // 对请求错误做些什么 
        console.log(err)
        return Promise.reject(err) // 在请求错误的时候的逻辑处理
    });

响应拦截器 ——在被then,catch处理前拦截

    // 添加响应拦截器
    axios.interceptors.response.use(res => {
      // 在请求成功后的数据处理 
      console.log(res)
      return res.data; // 对响应数据做点什么
    }, err=>{
        // 对响应错误做些什么
        console.log(err)
        return Promise.reject(err)  // 在响应错误的时候的逻辑处理
    });

封装网络请求函数 | 利用axios实例进行网络请求

export function request(config) {
    // 1. 创建axios实例
    const instance = axios.create({
      baseURL: "http://localhost:8080",
      timeout: 5000,
    });
    // ​2. axios拦截器的使用
    // 2.1 添加请求拦截器
    /** 需要拦截请求的原因
     *   1.config中包含了某些不符合服务器要求的信息
     *   2.发送网络请求的时候需要向用户展示一些加载中的图标
     *   3.网站需要登录才能请求资源,也就是需要token才能请求资源
     */
    instance.interceptors.request.use(
      (config) => {
        // 在发送请求之前做些什么
        return config; //拦截器里一定要记得将拦截的结果处理后返回,否则无法进行数据获取
      },
      (err) => {
        // 对请求错误做些什么
        return Promise.reject(err); // 在请求错误的时候的逻辑处理
      }
    );
    // 2.2 添加响应拦截器
    instance.interceptors.response.use(
      (res) => {
        // 在请求成功后对响应数据做处理
        return res; // 对响应数据做点什么
      },
      (err) => {
        // 对响应错误做些什么
        return Promise.reject(err); // 在响应错误的时候的逻辑处理
      }
    );
    // 3. 发送网络请求
    //axios实例本身返回的就是Promise对象,直接调用即可
    return instance(config);
}

XMLHttpRequest 的学习

 AJAX 是浏览器与服务器通信的技术,采用 XMLHttpRequest 对象相关代码

axios 是对 XHR 相关代码进行了封装,让我们只关心传递的接口参数

学习 XHR 也是了解 axios 内部与服务器交互过程的真正原理

const xhr = new XMLHttpRequest()
   xhr.open('请求方法', '请求url网址')
   xhr.addEventListener('loadend', () => {
     // 响应结果
     console.log(xhr.response)
   })
   xhr.send()

XMLHttpRequest_基础使用

 /**
        * 目标:使用XMLHttpRequest对象与服务器通信
        *  1. 创建 XMLHttpRequest 对象
        *  2. 配置请求方法和请求 url 地址
        *  3. 监听 loadend 事件,接收响应结果
        *  4. 发起请求
       */
       // 1. 创建 XMLHttpRequest 对象
       const xhr = new XMLHttpRequest()
   
       // 2. 配置请求方法和请求 url 地址
       xhr.open('GET', 'http://hmajax.itheima.net/api/province')
   
       // 3. 监听 loadend 事件,接收响应结果
       xhr.addEventListener('loadend', () => {
         console.log(xhr.response)
         const data = JSON.parse(xhr.response)
         console.log(data.list.join('<br>'))
         document.querySelector('.my-p').innerHTML = data.list.join('<br>')
       })
   
       // 4. 发起请求
       xhr.send()

使用XHR携带查询参数,展示某个省下属的城市列表

 /**
    * 目标:使用XHR携带查询参数,展示某个省下属的城市列表
   */
   const xhr = new XMLHttpRequest()
   xhr.open('GET', 'http://hmajax.itheima.net/api/city?pname=辽宁省')
   xhr.addEventListener('loadend', () => {
     console.log(xhr.response)
     const data = JSON.parse(xhr.response)
     console.log(data)
     document.querySelector('.city-p').innerHTML = data.list.join('<br>')
   })
   xhr.send()


. 但是多个查询参数,如果自己拼接很麻烦,这里用 URLSearchParams 把参数对象转成“参数名=值&参数名=值“格式的字符串,语法如下:

   ```js
   // 1. 创建 URLSearchParams 对象
   const paramsObj = new URLSearchParams({
     参数名1: 值1,
     参数名2: 值2
   })
   
   // 2. 生成指定格式查询参数字符串
   const queryString = paramsObj.toString()
   // 结果:参数名1=值1&参数名2=值2

了解原生 XHR 进行数据提交的方式

 const xhr = new XMLHttpRequest()
     xhr.open('POST', 'http://hmajax.itheima.net/api/register')
     xhr.addEventListener('loadend', () => {
       console.log(xhr.response)
     })
   
     // 设置请求头-告诉服务器内容类型(JSON字符串)
     xhr.setRequestHeader('Content-Type', 'application/json')
     // 准备提交的数据
     const userObj = {
       username: 'itheima007',
       password: '7654321'
     }
     const userStr = JSON.stringify(userObj)
     // 设置请求体,发起请求
     xhr.send(userStr)

认识_Promise

Promise 管理异步任务,语法:

// 1. 创建 Promise 对象
   const p = new Promise((resolve, reject) => {
    // 2. 执行异步任务-并传递结果
    // 成功调用: resolve(值) 触发 then() 执行
    // 失败调用: reject(值) 触发 catch() 执行
   })
   // 3. 接收结果
   p.then(result => {
    // 成功
   }).catch(error => {
    // 失败
   })


 /**
    * 目标:使用Promise管理异步任务
   */
   // 1. 创建Promise对象
   const p = new Promise((resolve, reject) => {
     // 2. 执行异步代码
     setTimeout(() => {
       // resolve('模拟AJAX请求-成功结果')
       reject(new Error('模拟AJAX请求-失败结果'))
     }, 2000)
   })
   
   // 3. 获取结果
   p.then(result => {
     console.log(result)
   }).catch(error => {
     console.log(error)
   })

Promise 管理 XHR 异步任务

 /**
    * 目标:使用Promise管理XHR请求省份列表
    *  1. 创建Promise对象
    *  2. 执行XHR异步代码,获取省份列表
    *  3. 关联成功或失败函数,做后续处理
   */
   // 1. 创建Promise对象
   const p = new Promise((resolve, reject) => {
     // 2. 执行XHR异步代码,获取省份列表
     const xhr = new XMLHttpRequest()
     xhr.open('GET', 'http://hmajax.itheima.net/api/province')
     xhr.addEventListener('loadend', () => {
       // xhr如何判断响应成功还是失败的?
       // 2xx开头的都是成功响应状态码
       if (xhr.status >= 200 && xhr.status < 300) {
         resolve(JSON.parse(xhr.response))
       } else {
         reject(new Error(xhr.response))
       }
     })
     xhr.send()
   })
   
   // 3. 关联成功或失败函数,做后续处理
   p.then(result => {
     console.log(result)
     document.querySelector('.my-p').innerHTML = result.list.join('<br>')
   }).catch(error => {
     // 错误对象要用console.dir详细打印
     console.dir(error)
     // 服务器返回错误提示消息,插入到p标签显示
     document.querySelector('.my-p').innerHTML = error.message
   })

封装_简易axios-获取省份列表

   1. 定义 myAxios 函数,接收配置对象,返回 Promise 对象

   2. 发起 XHR 请求,默认请求方法为 GET

   3. 调用成功/失败的处理程序

   4. 使用 myAxios 函数,获取省份列表展示

/**
    * 目标:封装_简易axios函数_获取省份列表
    *  1. 定义myAxios函数,接收配置对象,返回Promise对象
    *  2. 发起XHR请求,默认请求方法为GET
    *  3. 调用成功/失败的处理程序
    *  4. 使用myAxios函数,获取省份列表展示
   */
   // 1. 定义myAxios函数,接收配置对象,返回Promise对象
   function myAxios(config) {
     return new Promise((resolve, reject) => {
       // 2. 发起XHR请求,默认请求方法为GET
       const xhr = new XMLHttpRequest()
       xhr.open(config.method || 'GET', config.url)
       xhr.addEventListener('loadend', () => {
         // 3. 调用成功/失败的处理程序
         if (xhr.status >= 200 && xhr.status < 300) {
           resolve(JSON.parse(xhr.response))
         } else {
           reject(new Error(xhr.response))
         }
       })
       xhr.send()
     })
   }
   
   // 4. 使用myAxios函数,获取省份列表展示
   myAxios({
     url: 'http://hmajax.itheima.net/api/province'
   }).then(result => {
     console.log(result)
     document.querySelector('.my-p').innerHTML = result.list.join('<br>')
   }).catch(error => {
     console.log(error)
     document.querySelector('.my-p').innerHTML = error.message
   })

在上个封装的建议 axios 函数基础上,修改代码支持传递查询参数功能

  1. myAxios 函数调用后,判断 params 选项

   2. 基于 URLSearchParams 转换查询参数字符串

   3. 使用自己封装的 myAxios 函数显示地区列表

 function myAxios(config) {
     return new Promise((resolve, reject) => {
       const xhr = new XMLHttpRequest()
       // 1. 判断有params选项,携带查询参数
       if (config.params) {
         // 2. 使用URLSearchParams转换,并携带到url上
         const paramsObj = new URLSearchParams(config.params)
         const queryString = paramsObj.toString()
         // 把查询参数字符串,拼接在url?后面
         config.url += `?${queryString}`
       }
   
       xhr.open(config.method || 'GET', config.url)
       xhr.addEventListener('loadend', () => {
         if (xhr.status >= 200 && xhr.status < 300) {
           resolve(JSON.parse(xhr.response))
         } else {
           reject(new Error(xhr.response))
         }
       })
       xhr.send()
     })
   }
   
   // 3. 使用myAxios函数,获取地区列表
   myAxios({
     url: 'http://hmajax.itheima.net/api/area',
     params: {
       pname: '辽宁省',
       cname: '大连市'
     }
   }).then(result => {
     console.log(result)
     document.querySelector('.my-p').innerHTML = result.list.join('<br>')
   })

回调函数地狱

 概念:在回调函数中嵌套回调函数,一直嵌套下去就形成了回调函数地狱

 缺点:可读性差,异常无法捕获,耦合性严重,牵一发动全身

 axios({ url: 'http://hmajax.itheima.net/api/province' }).then(result => {
     const pname = result.data.list[0]
     document.querySelector('.province').innerHTML = pname
     // 获取第一个省份默认下属的第一个城市名字
     axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname } }).then(result => {
       const cname = result.data.list[0]
       document.querySelector('.city').innerHTML = cname
       // 获取第一个城市默认下属第一个地区名字
       axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname, cname } }).then(result => {
         document.querySelector('.area').innerHTML = result.data.list[0]
       })
     })
   })

Promise-链式调用

概念:依靠 then() 方法会返回一个新生成的 Promise 对象特性,继续串联下一环任务,直到结束

细节:then() 回调函数中的返回值,会影响新生成的 Promise 对象最终状态和结果

 好处:通过链式调用,解决回调函数嵌套问题

 /**
    * 目标:掌握Promise的链式调用
    * 需求:把省市的嵌套结构,改成链式调用的线性结构
   */
   // 1. 创建Promise对象-模拟请求省份名字
   const p = new Promise((resolve, reject) => {
     setTimeout(() => {
       resolve('北京市')
     }, 2000)
   })
   
   // 2. 获取省份名字
   const p2 = p.then(result => {
     console.log(result)
     // 3. 创建Promise对象-模拟请求城市名字
     // return Promise对象最终状态和结果,影响到新的Promise对象
     return new Promise((resolve, reject) => {
       setTimeout(() => {
         resolve(result + '--- 北京')
       }, 2000)
     })
   })
   
   // 4. 获取城市名字
   p2.then(result => {
     console.log(result)
   })
   
   // then()原地的结果是一个新的Promise对象
   console.log(p2 === p)

Promise-链式调用_解决回调

目标:使用 Promise 链式调用,解决回调函数地狱问题

做法:每个 Promise 对象中管理一个异步任务,用 then 返回 Promise 对象,串联起来

 /**
    * 目标:把回调函数嵌套代码,改成Promise链式调用结构
    * 需求:获取默认第一个省,第一个市,第一个地区并展示在下拉菜单中
   */
   let pname = ''
   // 1. 得到-获取省份Promise对象
   axios({url: 'http://hmajax.itheima.net/api/province'}).then(result => {
     pname = result.data.list[0]
     document.querySelector('.province').innerHTML = pname
     // 2. 得到-获取城市Promise对象
     return axios({url: 'http://hmajax.itheima.net/api/city', params: { pname }})
   }).then(result => {
     const cname = result.data.list[0]
     document.querySelector('.city').innerHTML = cname
     // 3. 得到-获取地区Promise对象
     return axios({url: 'http://hmajax.itheima.net/api/area', params: { pname, cname }})
   }).then(result => {
     console.log(result)
     const areaName = result.data.list[0]
     document.querySelector('.area').innerHTML = areaName
   })

async 函数和 await

概念:在 async 函数内,使用 await 关键字取代 then 函数,等待获取 Promise 对象成功状态的结果值

做法:使用 async 和 await 解决回调地狱问题

/**
    * 目标:掌握async和await语法,解决回调函数地狱
    * 概念:在async函数内,使用await关键字,获取Promise对象"成功状态"结果值
    * 注意:await必须用在async修饰的函数内(await会阻止"异步函数内"代码继续执行,原地等待结果)
   */
   // 1. 定义async修饰函数
   async function getData() {
     // 2. await等待Promise对象成功的结果
     const pObj = await axios({url: 'http://hmajax.itheima.net/api/province'})
     const pname = pObj.data.list[0]
     const cObj = await axios({url: 'http://hmajax.itheima.net/api/city', params: { pname }})
     const cname = cObj.data.list[0]
     const aObj = await axios({url: 'http://hmajax.itheima.net/api/area', params: { pname, cname }})
     const areaName = aObj.data.list[0]
   
   
     document.querySelector('.province').innerHTML = pname
     document.querySelector('.city').innerHTML = cname
     document.querySelector('.area').innerHTML = areaName
   }
   
   getData()

async 函数和 await 捕获错误

 try 和 catch 的作用:语句标记要尝试的语句块,并指定一个出现异常时抛出的响应

 try {
     // 要执行的代码
   } catch (error) {
     // error 接收的是,错误消息
     // try 里代码,如果有错误,直接进入这里执行
   }

尝试把代码中 url 地址写错,运行观察 try catch 的捕获错误信息能力

/**
    * 目标:async和await_错误捕获
   */
   async function getData() {
     // 1. try包裹可能产生错误的代码
     try {
       const pObj = await axios({ url: 'http://hmajax.itheima.net/api/province' })
       const pname = pObj.data.list[0]
       const cObj = await axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname } })
       const cname = cObj.data.list[0]
       const aObj = await axios({ url: 'http://hmajax.itheima.net/api/area', params: { pname, cname } })
       const areaName = aObj.data.list[0]
   
       document.querySelector('.province').innerHTML = pname
       document.querySelector('.city').innerHTML = cname
       document.querySelector('.area').innerHTML = areaName
     } catch (error) {
       // 2. 接着调用catch块,接收错误信息
       // 如果try里某行代码报错后,try中剩余的代码不会执行了
       console.dir(error)
     }
   }
   
   getData()

事件循环

作用:事件循环负责执行代码,收集和处理事件以及执行队列中的子任务

原因:JavaScript 单线程(某一刻只能执行一行代码),为了让耗时代码不阻塞其他代码运行,设计了事件循环模型

概念:执行代码和收集异步任务的模型,在调用栈空闲,反复调用任务队列里回调函数的执行机制,就叫事件循环

需求:请根据掌握的事件循环的模型概念,分析代码执行过程

/**
    * 目标:阅读并回答执行的顺序结果
   */
   console.log(1)
   setTimeout(() => {
     console.log(2)
   }, 0)
   function myFn() {
     console.log(3)
   }
   function ajaxFn() {
     const xhr = new XMLHttpRequest()
     xhr.open('GET', 'http://hmajax.itheima.net/api/province')
     xhr.addEventListener('loadend', () => {
       console.log(4)
     })
     xhr.send()
   }
   for (let i = 0; i < 1; i++) {
     console.log(5)
   }
   ajaxFn()
   document.addEventListener('click', () => {
     console.log(6)
   })
   myFn()

宏任务与微任务

 ES6 之后引入了 Promise 对象, 让 JS 引擎也可以发起异步任务

异步任务划分为了

   * 宏任务:由浏览器环境执行的异步代码

   * 微任务:由 JS 引擎环境执行的异步代码

  /**
    * 目标:阅读并回答打印的执行顺序
   */
   console.log(1)
   setTimeout(() => {
     console.log(2)
   }, 0)
   const p = new Promise((resolve, reject) => {
     resolve(3)
   })
   p.then(res => {
     console.log(res)
   })
   console.log(4)

 注意:宏任务每次在执行同步代码时,产生微任务队列,清空微任务队列任务后,微任务队列空间释放!

下一次宏任务执行时,遇到微任务代码,才会再次申请微任务队列空间放入回调函数消息排队

 总结:一个宏任务包含微任务队列,他们之间是包含关系,不是并列关系

事件循环 - 经典面试题

需求:请切换到对应配套代码,查看具体代码,并回答打印顺序(锻炼事件循环概念的理解,阅读代码执行顺序_)

 // 目标:回答代码执行顺序
   console.log(1)
   setTimeout(() => {
     console.log(2)
     const p = new Promise(resolve => resolve(3))
     p.then(result => console.log(result))
   }, 0)
   const p = new Promise(resolve => {
     setTimeout(() => {
       console.log(4)
     }, 0)
     resolve(5)
   })
   p.then(result => console.log(result))
   const p2 = new Promise(resolve => resolve(6))
   p2.then(result => console.log(result))
   console.log(7)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值