程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Axios

    • Axios - 引入
    • Axios - 发送请求
    • Axios - config 配置
    • async/await 处理 Axios 请求
    • Axions - 拦截器
      • 一、全局拦截器
      • 二、请求拦截器
      • 三、响应拦截器
      • 四、拦截器完整示例
  • Axios
  • Axios
scholar
2024-08-16
目录

Axions - 拦截器

# Axios 拦截器

Axios 拦截器(Interceptors)是一个非常实用的功能,允许在请求或响应被 then 或 catch 处理之前拦截它们。通过拦截器,我们可以在请求发送前或响应返回后执行额外的逻辑,如为每个请求添加认证 Token、统一处理错误响应、记录日志等。拦截器分为三类:全局拦截器、请求拦截器 和 响应拦截器。

# 一、全局拦截器

全局拦截器会影响所有通过 Axios 实例发出的请求。它通常用于配置每个请求都需要的通用设置,如 API 的基础 URL、默认请求头、超时时间等。

import axios from 'axios';

// 创建一个 Axios 实例
const axiosInstance = axios.create({
  baseURL: 'https://api.example.com', // 所有请求的基础 URL
  timeout: 10000, // 请求超时时间设置为 10 秒
  headers: {
    'Content-Type': 'application/json', // 默认请求头,指定内容类型
  }
});
1
2
3
4
5
6
7
8
9
10

关键点:

  • axios.create():创建一个带有全局配置的 Axios 实例,用于在项目中复用。
  • baseURL:配置请求的基础 URL,所有请求都会基于此 URL 进行拼接。
  • timeout:指定请求的超时时间,超时后请求会自动取消。
  • headers:设置请求的默认头部信息,如 Content-Type。

# 二、请求拦截器

请求拦截器在请求发出前被触发,可以用来修改请求配置、添加额外的请求信息(如 Token),或者进行一些全局的前置处理。这种拦截器的常见用途包括在请求头中添加认证信息、为所有请求统一添加公共参数、记录日志等。

// 添加请求拦截器
axiosInstance.interceptors.request.use(
  config => {
    // 请求发送前的处理逻辑

    // 从本地存储中获取 Token
    const token = localStorage.getItem('token');

    // 如果存在 Token,则将其添加到请求头部
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`;
    }

    // 在这里添加公共参数、修改请求配置等
    // 例如为所有请求添加一个语言参数 'lang'
    config.params = { 
      ...config.params, // 保留已有的参数
      lang: 'en' // 添加公共的 'lang' 参数
    };

    // 打印当前请求的配置(用于调试)
    console.log('请求配置:', config);

    // 返回修改后的配置对象,以继续请求的流程
    return config;
  },
  error => {
    // 请求错误处理
    console.error('请求错误:', error);
    
    // 返回 Promise.reject 以确保错误被捕获
    return Promise.reject(error);
  }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

关键点:

  • config:请求的配置对象,可以动态修改请求头、参数等。
  • Authorization:通常用于在请求头中携带认证信息(如 Token)。
  • config.params = { ...config.params, lang: 'en' };:使用 JavaScript 的展开语法,将现有的查询参数展开,并添加一个新的公共参数 lang: 'en'。这适用于需要在所有请求中统一传递某些参数的场景。

# 三、响应拦截器

响应拦截器在收到响应数据后触发,可以用来统一处理响应数据、拦截错误响应等。常见的应用场景包括根据状态码进行错误处理、全局处理错误信息等。

// 添加响应拦截器
axiosInstance.interceptors.response.use(
  response => {
    // 处理成功的响应数据
    if (response.status === 200) {
      return response.data; // 直接返回数据,简化后续处理
    } else {
      // 非 200 状态码处理
      return Promise.reject(new Error('请求失败,状态码:' + response.status));
    }
  },
  error => {
    // 响应错误处理
    if (error.response) {
      // 根据状态码处理不同的错误
      switch (error.response.status) {
        case 401:
          console.error('未授权,请重新登录');
          break;
        case 403:
          console.error('权限不足,拒绝访问');
          break;
        case 500:
          console.error('服务器内部错误');
          break;
        default:
          console.error('其他错误:', error.response.status);
      }
    } else if (error.request) {
      // 请求已发送但未收到响应
      console.error('请求超时或网络异常');
    } else {
      // 处理其他错误
      console.error('请求出错:', error.message);
    }
    return Promise.reject(error); // 返回 Promise.reject 以确保错误被捕获
  }
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

关键点:

  • response:响应对象,可以在这里对返回的数据进行统一预处理。
  • 常见用法:根据状态码处理错误、记录错误日志、处理网络异常等。

# 四、拦截器完整示例

您提到的场景非常常见,通常在本地存储(如 localStorage 或 sessionStorage)中保存的是后端返回的用户信息对象,里面包括 token 以及用户的其他信息。我们可以在请求拦截器中提取这个信息,并在发送请求时将 token 添加到请求头中。

这里是根据这种需求重新编写的代码:

import axios from 'axios';
import router from '@/router';
import { Message } from 'element-ui'; // 引入 Element UI 的 Message 模块

// 创建 Axios 实例
const axiosInstance = axios.create({
  baseURL: 'https://api.example.com', // 全局基础 URL
  timeout: 10000, // 设置请求超时时间为 10 秒
  headers: {
    'Content-Type': 'application/json' // 设置默认的内容类型为 JSON
  }
});

// 请求拦截器
axiosInstance.interceptors.request.use(
  config => {
    // 从本地存储中获取缓存的用户信息
    const user = JSON.parse(localStorage.getItem('user') || '{}');
    
    // 如果用户信息存在,并且包含 token
    if (user && user.token) {
      config.headers['Authorization'] = `Bearer ${user.token}`; // 为每个请求添加 Authorization 头
    }

    // 例如可以统一添加公共参数
    config.params = { ...config.params, lang: 'en' }; // 为所有请求添加语言参数
    console.log('请求拦截器配置:', config);
    return config; // 返回修改后的请求配置对象
  },
  error => {
    // 请求错误处理
    console.error('请求错误:', error);
    Message.error('请求发送失败,请检查网络或稍后再试'); // 添加错误提示
    return Promise.reject(error); // 确保错误被捕获
  }
);

// 响应拦截器
axiosInstance.interceptors.response.use(
  response => {
    // 在响应数据返回之前做一些处理
    if (response.status === 200) {
      console.log('响应成功:', response);
      return response.data; // 直接返回数据,简化业务代码
    } else {
      Message.error('请求失败,状态码:' + response.status); // 添加错误提示
      return Promise.reject(new Error('请求失败,状态码:' + response.status));
    }
  },
  error => {
    // 响应错误处理
    if (error.response) {
      // 服务器返回的错误,根据状态码进行不同处理
      const status = error.response.status;
      switch (status) {
        case 401:
          Message.error('登录已过期,请重新登录');
          // 清除本地存储中的用户信息
          localStorage.removeItem('user');
          router.push('/login'); // 跳转到登录页面
          break;
        case 403:
          Message.error('权限不足,拒绝访问');
          break;
        case 404:
          Message.error('请求资源未找到');
          break;
        case 500:
          Message.error('服务器内部错误,请稍后再试');
          break;
        default:
          Message.error('请求出错,状态码:' + status);
      }
    } else if (error.request) {
      // 请求已发送但未收到响应
      Message.error('请求超时或网络异常');
    } else {
      // 其他错误处理
      Message.error('请求出错:' + error.message);
    }
    return Promise.reject(error); // 确保错误被捕获
  }
);

// 导出 Axios 实例,供业务代码使用
export default axiosInstance;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

关键点说明:

  1. 本地存储用户信息:

    • 我们假设在本地存储中保存的是一个包含 token 和其他用户信息的对象。比如:
    {
      "username": "user123",
      "token": "your-jwt-token"
    }
    
    1
    2
    3
    4

    这个对象保存在 localStorage 中的 user 键下。

  2. 在请求拦截器中添加 Authorization 头:

    • 在请求拦截器中,我们首先从本地存储获取用户信息,并检查是否包含 token。如果存在,则将其添加到请求头中。
  3. 处理未授权状态:

    • 如果响应状态码为 401,表示未授权,我们将清除本地存储中的用户信息,并跳转到登录页面。
  4. 更友好的错误提示:

    • 每个错误处理分支中都添加了 Element UI 的 Message.error,确保用户可以清楚了解当前发生的错误。
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
async/await 处理 Axios 请求

← async/await 处理 Axios 请求

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式