Axios:请求响应拦截器
如果每次发送网络请求都要手动携带上token,这无疑是加剧了工作量。借助工程化中模块化的思想,如果我设置个统一处理网络请求的模块,就可以完美解决这个问题。于是,axiso中的请求响应拦截器由此而生。
为什么要做拦截器
原因
- 统一处理请求和响应
- 请求 拦截器:可以在每个请求发送之前对请求进行处理。例如,可以在所有请求中添加认证 token,设置统一的 headers,或者进行参数校验。
- 响应 拦截器:可以在每个响应到达之前对响应进行处理。例如,可以统一处理错误,解析响应数据,或者重定向到登录页面。
- 错误处理
- 通过响应拦截器,可以统一捕获和处理错误。例如,可以在拦截器中检查响应状态码,如果是 401(未授权)状态码,可以自动刷新 token 或者跳转到登录页面。
- 方便数据转换
- 可以在请求发送之前或响应到达之后对数据进行转换。例如,可以在请求拦截器中将请求的数据转换为所需的格式,或者在响应拦截器中将响应的数据转换为更易于使用的格式。
之于工程化的意义
代码简洁和可维护性:
- 使用拦截器可以避免在每个请求或响应中重复编写相同的逻辑,提升代码的简洁性和可维护性。例如,统一的错误处理逻辑可以在拦截器中实现,而不是分散在每个请求中。
一致性:
- 拦截器可以确保所有请求和响应都经过相同的处理逻辑, 保证行为的一致性。例如,可以确保每个请求都携带认证信息,或每个错误都经过统一的处理。
灵活性和扩展性:
- 拦截器使得请求和响应的处理更加灵活和可扩展。例如,可以根据不同的业务需求动态添加或移除拦截器,实现不同的功能。
总结来说,Axios 的拦截器功能通过在请求和响应处理过程中提供统一的处理机制,使得代码更加简洁、可维护、一致,并提升了系统的灵活性和扩展性。这些都是现代前端工程化实践中的重要组成部分。
怎么使用(配置)拦截器
设置拦截器
我们在
src > utils
文件夹下 封装一个request.js
文件
- 创建并自定义一个Axios实例
baseURL
:定义了请求的基础 URL。所有通过这个实例发送的请求都会使用这个 URL 作为基准路径。
1import axios from 'axios'
2import { useUserStore } from '@/stores'
3import router from '@/router'
4import { ElMessage } from 'element-plus'
5const baseURL = 'http://127.0.0.1:80'
6
7const instance = axios.create({
8 baseURL,
9 timeout: 10000
10})
11
- 配置请求 拦截器
instance.interceptors.request.use
:为 Axios 实例添加一个请求拦截器。(config) => { ... }
:这是请求拦截器的成功处理函数,当请求发送之前会调用这个函数。(err) => Promise.reject(err)
:这是请求拦截器的错误处理函数,如果请求配置阶段出错,会调用这个函数并返回一个被拒绝的 Promise。
1instance.interceptors.request.use(
2 (config) => {
3 const useStore = useUserStore() // 获取用户状态
4 // 检查并添加token
5 if (useStore.token) {
6 config.headers.Authorization = useStore.token
7 }
8 return config // 返回配置
9 },
10 (err) => Promise.reject(err) // 错误处理
11)
12
- 配置响应 拦截器
if (res.data.code === 0)
:假设 API 返回的数据中包含code
字段,表示业务状态码。code
为0
表示业务成功。这里检查res.data.code
是否为0
,如果是,则认为业务成功,直接返回响应数据。ElMessage.error(res.data.message || '服务异常')
:如果code
不为0
,则认为业务失败,使用 Element Plus 的消息提示组件显示错误信息。res.data.message
包含具体的错误信息,如果没有,则显示默认的 '服务异常'。return res
:业务成功时返回完整的响应对象res
。return Promise.reject(res.data)
:业务失败时返回一个被拒绝的 Promise,传递res.data
以便在后续链式调用中处理。if (err.response?.status === 401)
:检查响应的状态码是否为401
(未授权)。如果是,则跳转到登录页面。router.push('/login')
:使用 Vue 路由器将用户重定向到登录页面。
1instance.interceptors.response.use(
2 // 成功响应处理函数
3 (res) => {
4 if (res.data.code === 0) {
5 return res // 没问题就返回数据 res
6 }
7 // 否则就是有问题,返回以恶个被拒绝的 promise 状态。
8 ElMessage.error(res.data.message || '服务异常')
9 return Promise.reject(res.data)
10 },
11 (err) => {
12 if (err.response?.status === 401) {
13 router.push('/login')
14 }
15 ElMessage.error(err.response.data.message || '服务异常')
16 return Promise.reject(err)
17 }
18)
19
响应拦截器的思路就是:
- 如果成功,就返回数据。
- 如果失败就统一处理
- 导出模块
1export default instance
2
使用
假设现在有一个api模块,是用来处理网络请求的。
- 封装接口
在src > api 模块新建一个
handleData.js
1import request from '@/utils/request' // 导入模块
2
3// 导出具体处理请求
4export const handleDate = ( data ) => request.post('/handledata', data)
5
- 使用接口
假设在
index.vue
中使用
涉及网络请求,所以异步处理。
1import { handleData } from '@/api/handleData.js'
2
3const myData = ref('Hello world, I am mCell.')
4
5const postData = async () => {
6 await handleData(myData.value)
7}
8postData()
9
相关笔记