Axios

网络请求
概述 Overview
异步请求;基于 Promise 的 HTTP 库,广泛应用于浏览器和 Node.js
通用、主流的第三方库;用于获取本地和远程资源,如 JSON 数据、图片等
默认是 Promise 用法;支持 async/await 用法
自动转换 JSON 数据
资源服务器应提前开启,并严格按照接口使用
更多信息,点击访问 Axios 中文网Axios vs Fetch
安装 Installment
在项目目录安装
npm i axios
也可以使用CDN方式,如 cdnjsbootcdn - 适合浏览器环境;建议将库下载到本地使用。。。CDN网络经常。。。
保留 crossorigin="anonymous" 避免浏览器提示
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.7.8/axios.min.js" crossorigin="anonymous"></script>
基本使用 Usage
先引入后使用 - 哪个组件需要就在哪个组件内操作
import axios from 'axios'
承诺方式 Promise
链式调用:axios().then().catch().finally()
通过配置使用,语法比较统一 - get 使用 data 传递参数;post 使用 params 传递参数
axios({
  method: 'get',
  url: '',
  params: {  }
})
// 履行处理器 fulfillment handle:处理成功情况
.then(res=>{
  console.log(res);
})
// 拒绝处理器 rejection handle:处理错误情况
.catch(err=>{
  console.log(err);
})
// 解决处理器:无论成功失败都执行
.finally(()=>{
  console.log('finally');
})
axios({
  method: 'post',
  url: '',
  data: {  }
})
.then(res)
.catch(err)
.finally()
或根据已经封装好的请求使用,如 get
axios.get(url)
  .then((res) => {    
    console.log(res);
  })
  .catch((err) => {    
    console.log(error);
  })
  .finally(() => {
    console.log('finally');
})
异步等待方式 async - await;可以有效避免回调地狱
需要声明为异步函数
1. 不捕获异常
async function getUser() {
    const response = await axios.get(url);
    console.log(response);
}
2. 捕获异常:try{}catch(){}finally{}
async function getUser() {
  try {
    const response = await axios.get(url);
    console.log(response);
  } catch (error) {
    console.error(error);
  } finally {    
    console.log('finally');
  }
}
或:函数表达式
let getUser = async () =>{
  try {
    const response = await axios.get(url);
    console.log(response);
  } catch (error) {
    console.error(error);
  } finally {    
    console.log('finally');
  }
}
需要通过 代理 解决跨域的问题
静态网站托管平台通常已经做了跨域处理,可以直接使用
封装 Encapsulation / Modulation
1. 配置
创建文件 request.js:指定请求URL、响应时间、拦截器等
import axios from "axios";

const request = axios.create({
  baseURL: "https://glpla.github.io/utils/data/", // 设置基础 URL
  timeout: 5000, // 请求超时时间
});

// interceptors 拦截器,见后续内容

export default request;
2. 封装
封装请求方法,仅仅是请求,响应放在使用中处理
创建文件 goods.js:引入配置文件、处理商品数据的加载等事件
import requset from "./request";

export const getGoods = () => requset.get("coffee.json");
// 示例
export const getGoodByid = (id) => requset.get();
用户类的封装 user.js
import requset from "./request";

// 示例
export const login = (data) => requset.post();
export const register = (data) => requset.post();
export const update = (data) => requset.patch();
3. 使用
引入商品封装文件,使用其中的方法发起请求并处理结果
如在某个组件的生命周期函数中,请求数据 - 这里使用异步等待方式,也可以使用回调方式
import { getGoods } from '../assets/api/goods.js';

onMounted(async () => {
  const res = await getGoods()
  console.log(res);
})
改进1:加入错误控制
onMounted(async () => {
  try {
    const res = await getGoods()
    console.log(res);
  } catch (error) {
    console.log(error);
  }
})
改进2:加入进度指示器
onMounted(async () => {
  console.log('loading start');

  try {
    const res = await getGoods()
    console.log(res);
  } catch (error) {
    console.log(error);
  } finally {
    console.log('laoding done');
  }
})
在 src 下创建 api 文件夹管理相关文件
拦截器 interceptor
拦截器
请求拦截器 request
目的:限制访问;发出去的请求是经过处理后的请求;如配置请求,如请求头、指定 Token 用来验证身份
在请求发送前:
. 对 请求参数 进行拦截,修改参数
. 对 请求头 进行拦截,修改请求头
. 对 请求体 进行拦截,修改请求体
axios.interceptors.request.use( 
  (config) => {
    // ...
    // config.headers.Authorization = 'Bearer ' + token;
    return config;
  },
  (error) => {
    // ...
    return Promise.reject(error)
  }
)
响应拦截器 response
目的:过滤响应数据;接受到的响应是经过处理后的响应
在请求返回后:
. 对 响应数据 进行拦截,修改响应数据
. 对 响应头 进行拦截,修改响应头
. 对 响应头 进行拦截,修改响应体
axios.interceptors.response.use( 
  (response) => {
    // ...
    return response;
  },  
  (error) => {
    // ...
    return Promise.reject(error);
  }
)
趣味应用 application
[] 获取远程数据 -
https://dog.ceo/api/breed/pembroke/images/random
[] 获取本地数据 -
1. 如何渲染获取到的数据?使用新节点?使用innerHtml?
2. 表格<table>的使用:使用默认表格还是特别指定表头<thead>和表体<tbody>?
序号 内容 难度
//使用节点
for (let i = 0; i < res.data.length; i++) {
let tr = document.createElement('tr')
for (let item in res.data[i]) {
    let td = document.createElement('td')
    td.innerHTML = res.data[i][item]
    tr.appendChild(td)
}
axiosLocal.appendChild(tr)
}
//使用innerHtml
for (let i = 0; i < res.data.length; i++) {
let tr = ''
for (let item in res.data[i]) {
    tr += '' + res.data[i][item] + ''
}
tr += ''
axiosLocal.innerHTML += tr
}