傲渊山岳 发表于 2024-11-9 09:57:44

使用 axios 拦截器实现哀求和相应的同一处置惩罚(附常见口试题)

在现代前端开辟中,我们常常需要向服务器发送 HTTP 哀求,并根据相应内容做差别的处置惩罚。axios 是一个流行的 HTTP 库,提供了 拦截器 功能,可以在哀求和相应阶段插入自定义逻辑,这使得我们在处置惩罚认证、错误提示等场景时更为简洁、同一。
本文将讲解如何使用 axios 的哀求拦截器和相应拦截器来处置惩罚 token、重定向、错误提示等场景,并附上一些常见的口试问题。
一、代码实现

首先,我们来看一个使用 axios 的拦截器实例代码:
import axios, { type AxiosResponse } from 'axios'
import router from '@/router'
import { ElMessage } from 'element-plus'
import { ResultEnum } from '@/enums/ResultEnum'
import { TOKEN_KEY } from '@/enums/SystemEnum'

// 创建 axios 实例
const AXIOS = axios.create({
baseURL: '/lili-api',
headers: {
    'Content-Type': 'application/json;charset=utf-8'
}
})

// 请求拦截器
AXIOS.interceptors.request.use(
(config) => {
    // 从 localStorage 中获取 token
    const token = localStorage.getItem(TOKEN_KEY)
   
    if (token) {
      // 确保 headers 存在
      config.headers = config.headers || {}
      config.headers.Authorization = `Bearer ${token}`// 使用标准的 Bearer 认证方式
    }
    return config
},
(error) => {
    console.error("请求错误:", error)
    return Promise.reject(error)
}
)

// 响应拦截器
AXIOS.interceptors.response.use(
(response) => {
    const { code, message } = response.data

    switch (code) {
      case ResultEnum.NO_AUTH:
      // 无权限,清除 token 并重定向
      localStorage.removeItem(TOKEN_KEY)
      router.push('/login')
      break
      case ResultEnum.LOGIN_FAIL:
      // 登录失败,显示消息并清除 token
      ElMessage.error(message || "登录失败")
      localStorage.removeItem(TOKEN_KEY)
      break
      case ResultEnum.SUCCESS:
      // 成功响应,直接返回 data
      return response.data as AxiosResponse<HttpResponse>
      default:
      // 其他错误状态,显示错误消息
      if (message) {
          ElMessage.error(message)
      }
      break
    }
   
    return response.data
},
(error) => {
    // 响应错误的处理
    if (error.response) {
      ElMessage.error(`请求错误:${error.response.status}`)
    } else {
      ElMessage.error("网络错误,请检查您的网络连接")
    }
    console.error("响应错误:", error)
    return Promise.reject(error)
}
)

export default AXIOS
二、代码详解

让我们一步步分析这个代码实现。
1. 创建 axios 实例

const AXIOS = axios.create({
baseURL: '/lili-api',
headers: {
    'Content-Type': 'application/json;charset=utf-8'
}
})
这里用 axios.create() 创建了一个 axios 实例 AXIOS。这样做的好处是可以给该实例绑定一个特定的基础 URL (baseURL),以后所有用 AXIOS 发送的哀求都会主动加上这个 URL 前缀,省去了我们在每个哀求里手动写基础路径的麻烦。
2. 哀求拦截器

AXIOS.interceptors.request.use(
(config) => {
    const token = localStorage.getItem(TOKEN_KEY)
   
    if (token) {
      config.headers = config.headers || {}
      config.headers.Authorization = `Bearer ${token}`// 使用标准的 Bearer 认证方式
    }
    return config
},
(error) => {
    console.error("请求错误:", error)
    return Promise.reject(error)
}
)
哀求拦截器会在每个哀求发送前实行,它重要用来:


[*]检查 localStorage 是否有 token。如果有,将其添加到哀求头的 Authorization 字段,以 Bearer 格式添加,更符合 RESTful API 认证尺度。
[*]添加 Content-Type 为 application/json;charset=utf-8,表示哀求体的数据格式是 JSON。
[*]使用 console.error 方便调试,输出哀求拦截阶段的错误。
3. 相应拦截器

AXIOS.interceptors.response.use(
(response) => {
    const { code, message } = response.data

    switch (code) {
      case ResultEnum.NO_AUTH:
      localStorage.removeItem(TOKEN_KEY)
      router.push('/login')
      break
      case ResultEnum.LOGIN_FAIL:
      ElMessage.error(message || "登录失败")
      localStorage.removeItem(TOKEN_KEY)
      break
      case ResultEnum.SUCCESS:
      return response.data as AxiosResponse<HttpResponse>
      default:
      if (message) {
          ElMessage.error(message)
      }
      break
    }
   
    return response.data
},
(error) => {
    if (error.response) {
      ElMessage.error(`请求错误:${error.response.status}`)
    } else {
      ElMessage.error("网络错误,请检查您的网络连接")
    }
    console.error("响应错误:", error)
    return Promise.reject(error)
}
)
相应拦截器重要功能是根据相应的状态码做出差别处置惩罚:


[*]ResultEnum.NO_AUTH:无权限状态,清除 token,并重定向到登录页。
[*]ResultEnum.LOGIN_FAIL:登录失败状态,弹堕落误提示,并清除 token。
[*]ResultEnum.SUCCESS:哀求乐成时,直接返回数据。
[*]其他错误:在 switch 语句中处置惩罚其他未知状态码,弹堕落误信息提示。
同时,为了更全面地处置惩罚错误环境,相应错误 error 的处置惩罚阶段会显示更详细的状态码错误信息,或者在网络错误时给予用户相应提示。
三、口试中的常见问题

下面总结一些口试中关于 axios 拦截器的常见问题及答案示例:
1. 拦截器的作用是什么?

答复示例:拦截器答应我们在哀求发出前和相应返回后插入自定义逻辑。常见用途包括在哀求前检查认证 token 并添加到哀求头、在相应后根据状态码处置惩罚错误、主动重定向等。拦截器可以减少代码重复,使哀求的处置惩罚更集中、同一。
2. 为什么使用 axios.create 而不是直接用 axios?

答复示例:axios.create 创建了一个独立的 axios 实例,可以在这个实例上设置独特的基础配置,比如 baseURL、超时时间等。这种方式更模块化,实用于差别的 API,有助于项目中差别哀求模块的管理。
3. 为什么要在哀求头中设置 Content-Type?

答复示例:Content-Type 告诉服务器哀求体的数据格式。设置为 application/json,表示我们发送的数据是 JSON 格式,这样服务器就知道如何解析哀求数据。这种设置在 RESTful API 中是很常见的。
4. 为什么在无权限和登录失败时清除 token?

答复示例:NO_AUTH 和 LOGIN_FAIL 表示当前的 token 已失效(过期或被篡改)。为了安全性,我们在这种环境下会清除 token 并重定向到登录页,这样可以确保用户在下一次哀求前先重新登录,获取新的 token。
5. 相应拦截器返回 response.data as AxiosResponse<HttpResponse> 的作用是什么?

答复示例:response.data as AxiosResponse<HttpResponse> 是为了确保相应数据符合 HttpResponse 类型,让代码获得类型提示和安全检查的好处。这对 TypeScript 项目尤为紧张,可以及时发现类型不匹配的问题,提拔代码的可靠性。
6. 如何在拦截器中实现全局的加载动画?

答复示例:可以在哀求拦截器和相应拦截器中控制加载动画的显示和隐藏。在哀求拦截器里显示加载动画,在相应完成或失败时隐藏它。通过全局状态管理工具(如 Vuex)控制 loading 状态,可以实现全局的加载效果。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 使用 axios 拦截器实现哀求和相应的同一处置惩罚(附常见口试题)