文章目录
1.对axios进行二次封装的场景
主要是要用到请求拦截器和响应拦截器;
请求拦截器:可以在发请求之前可以处理一些业务
响应拦截器:当服务器数据返回以后,可以处理一些事情
2.axios二次封装的目的?
二次封装axios是为了方便我们后续项目的使用,
对api进行同一管理,不管接口有多少,可以让接口变得清晰和容易维护
如果页面非常的少,可以直接用axios不用二次封装,
如果页面组件一旦多了起来,上百个接口,后端改了接口,多加了一个参数,
只有找到那个页面,进去修改.整个过程很繁琐不易于项目的维护和迭代.
3.axios的原理,基于什么实现的?
axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
axios还是属于 XMLHttpRequest, 因此需要实现一个ajax;
还需要一个promise对象来对结果进行处理。
4.示例一:创建api/request.js用于书写axios二次封装的代码
import axios from "axios"//导入axios
//1.利用axios对象的create方法创建一个axios实例
const requests=axios.create({
//配置对象
baseURL:"./api",//基础路径
timeout:5000//请求时间
});
//2.请求拦截器:发送请求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情
requests.interceptors.request.use(config=>{
return config;//config是一个配置对象,对象里面有个属性很重要:headers请求头
});
//3.响应拦截器:包含两个函数:成功返回的函数和失败返回的函数
requests.intercateors.response.use(res=>{
return res.data;//成功的回调:服务器相应数据回来后响应拦截器可以检测到,可以做一些事情
},error=>{
return promise.reject(new Error("failed.."));//失败的回调
});
//4.对外暴露requests(axios的二次封装)
export default requests;
5.对api进行同一管理:请求的接口比较多,需要进行统一管理
创建api/index.js进行接口的统一管理
//导入axios二次封装的requests
import requests from "./requests"
//发送请求:axios发送请求返账结果(promise对象)
export const reqCatrgoryList=()=>{//三级联动接口
return requests({
url:"./product/getBaseCategoryList",//前面已经配置了基础路径,因此不用加/api
method:"get"
});
}
6.示例二:封装get,post请求,并携带token控制
import axios from "axios";//引入axios
import qs from 'qs'//第三方类库
//1.配置axios实例
axios.defaults.baseURL='./api;//配置基础路径
axios.defaults.timeout=10000 //请求时间
axios.defaults.withCredentials=true ;//例如:登录校验session和cookie
/**
* 设置请求数据参数传递的格式,默认是json格式,但是在登录校验中后台一般设置请求格式:x-www-form-urlencoded(name=xxx,age=xxx)
* 看服务器要求什么格式
*/
axios.defaults.headers['Content-Type']='application/x-www-form-urlencoded' //声明请求格式
axios.defaults.transformRequest=data=>qs.stringify(data) //qs是第三方库,转换为x-www-form-urlencoded
//2.设置请求拦截器(重点)
/**
* 设置请求拦截器:----在项目中发请求(请求没有发出去)可以做一些事情
* 客户端->[请求拦截器]->服务器端
* token校验(JWT):接收到服务器的token,存储到vuex/本地存储中,每次向服务器发送请求,我们应该把token带上
* config :发起请求的请求配置项
*/
axios.interceptors.request.use(config=>{
let token=localStorage.getItem('token')//token校验
token && (config.headers.Authoriztion=token)
return config
},error=>{
return Promise.reject(error)
})
/**
* 设置响应拦截器
* 服务器端返回信息->[响应拦截器]->客户端js获取到信息
* response中包含属性:
* data:相应数据,status:响应状态码,statusText:响应状态信息,headers:响应头,config:响应提供的配置信息,request
*/
axios.interceptors.response.use(response=>{
return response.data //将主体内容返回 axios.get().then(result=>{拿到的就是响应主体})
},error=>{
let { response}=error
// 如果有返回结果
if(response){
switch(response.status){
//这里面根据公司需求进行写
case 404:
//进行错误跳转之类
break;
}
}else{
//服务器没有返回结果 分两种情况 断网 服务器崩了
if(!window.navigator.onLine){
//断网处理:跳转到断网页面
return
}
return Promise.reject(error)
}
})
7.对比:不使用二次封装的调用有多麻烦?
在未封装统一请求工具的项目中,每个请求都需要重复处理所有细节:
// 商品详情页 - 获取商品数据
uni.request({
url: 'http://pcapi-xiaotuxian-front-devtest.itheima.net/goods/detail?id=123',
method: 'GET',
header: {
'source-Client': 'miniapp',
'Authorization': wx.getStorageSync('token') || '' // 手动处理token
},
timeout: 10000,
success: (res) => {
if (res.statusCode === 401) {
// 重复的401处理逻辑
uni.showToast({ title: '请重新登录' })
uni.navigateTo({ url: '/pages/login/index' })
} else if (res.statusCode >= 200 && res.statusCode < 300) {
this.goodsData = res.data.result
}
},
fail: (err) => {
uni.showToast({ title: '网络异常' }) // 重复的错误提示
}
})
// 用户页面 - 获取用户信息
uni.request({
url: 'http://pcapi-xiaotuxian-front-devtest.itheima.net/member/profile',
method: 'GET',
header: {
'source-Client': 'miniapp',
'Authorization': wx.getStorageSync('token') || '' // 重复提取token
},
timeout: 10000,
success: (res) => {
if (res.statusCode === 401) {
// ⚠️再写一遍401处理
uni.showToast({ title: '请重新登录' })
uni.navigateTo({ url: '/pages/login/index' })
}
// ...其他处理
}
})
缺点:
- 重复代码:每个请求都要处理token、超时、错误
- 维护困难:基础地址变更需修改所有请求
- 逻辑分散:401等状态码处理逻辑散落在各处
- 无类型安全:缺少TS类型约束
- 参数处理混乱:手动拼接URL参数效率低下3
封装 http.ts 后的调用方式:
step0:在http.ts中对axios进行二次封装,略
step1:统一调用接口
// 商品页面调用示例
import { http } from '@/utils/http'
const fetchGoods = async () => {
try {
// 只需要关注业务参数
const res = await http<GoodsItem>({
url: '/goods/detail',
method: 'GET',
data: { id: 123 } // 参数自动处理
})
this.goodsData = res.result // 类型安全访问
} catch (e) {
console.log('业务错误处理')
}
}
step2:创建 api 目录统一管理接口
// api/goods.ts
import { http } from '@/utils/http'
// 明确定义商品数据类型
interface GoodsItem {
id: number
name: string
price: number
}
export const getGoodsDetail = (id: number) => {
return http<GoodsItem>({
url: '/goods/detail',
method: 'GET',
data: { id }
})
}
// api/user.ts
export const getUserProfile = () => {
return http<UserProfile>({
url: '/member/profile',
method: 'GET'
})
}
step3:页面中调用,非常简洁
<script setup>
import { getGoodsDetail } from '@/api/goods'
import { getUserProfile } from '@/api/user'
const loadData = async () => {
const goods = await getGoodsDetail(123)
const user = await getUserProfile()
// 类型安全访问
console.log(goods.result.price)
console.log(user.result.nickname)
}
</script>
优点:
- 开发效率提升:减少 40%+ 重复代码
- 维护成本降低:核心逻辑单点维护
- 代码质量提升:类型安全 + 统一规范
- 用户体验优化:统一错误提示和处理流程

本文探讨了在前端开发中对axios进行二次封装的原因和场景,包括利用请求和响应拦截器,以及为了便于接口管理和维护。同时,通过示例介绍了如何创建api/request.js文件进行封装,并展示了如何在api/index.js中统一管理接口,以及封装带token控制的get和post请求。

2067

被折叠的 条评论
为什么被折叠?



