• 从零开始搭建React+TypeScript+webpack开发环境-基于axios的Ajax请求工具


    什么是axios

    axios是一款基于Promise的HTTP客户端,适用于浏览器和Node.js环境。它的特点包括:

    1. 支持浏览器和Node.js环境。
    2. 支持Promise API。
    3. 支持拦截请求和响应。
    4. 支持取消请求。
    5. 自动转换JSON数据。
    6. 支持CSRF保护。

    使用axios可以更方便地发送HTTP请求,并且对请求和响应进行拦截、转换等处理。它可以在浏览器端和Node.js环境中使用,很适用于进行数据交互。

    安装axios

    yarn add axios
    
    • 1

    创建token工具方法

    // 定义访问令牌的常量键名
    export const ACCESS_TOKEN = 'access_token';
    
    // 获取访问令牌
    export const getAccessToken = () => {
      return localStorage.getItem(ACCESS_TOKEN);
    };
    
    // 设置访问令牌
    export const setAccessToken = (token: string) => {
      localStorage.setItem(ACCESS_TOKEN, token);
    };
    
    // 移除访问令牌
    export const removeAccessToken = () => {
      localStorage.removeItem(ACCESS_TOKEN);
    };
    
    // 用于模拟刷新令牌的函数,可根据实际需求替换为真实刷新逻辑
    export const refreshAccessToken = async () => {
      return Promise.resolve('123456'); // 返回新的令牌
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    request工具方法

    当然,以下是一个更具体的分步骤介绍代码块的 Markdown 博文示例:

    创建 Axios 实例

    首先,我们需要创建一个 Axios 实例并配置默认请求头。这个实例将用于所有的网络请求。以下是创建 Axios 实例的示例代码:

    import axios, { AxiosInstance, AxiosResponse, AxiosError } from 'axios';
    import { API_HOST, LOGIN_URL } from './config';
    
    // 创建一个 Axios 实例并配置默认请求头
    const instance: AxiosInstance = axios.create({
      baseURL: API_HOST, // 设置基本 URL
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    请求拦截器

    请求拦截器用于修改请求配置,例如添加身份验证标头。以下是请求拦截器的示例代码:

    instance.interceptors.request.use(
      (config) => {
        let { url } = config;
        if (!url) {
          throw new Error('url不能为空');
        }
    
        if (url.indexOf('://') === -1) {
          url = `${API_HOST}${url}`;
        }
    
        const modifiedConfig = { ...config, url };
    
        if (!(modifiedConfig.data instanceof FormData)) {
          modifiedConfig.headers['Content-Type'] = 'application/json';
        }
    
        // 如果有访问令牌,将其添加到请求头
        const token = getAccessToken();
        if (token) {
          modifiedConfig.headers.Authorization = `JWT ${token}`;
        }
    
        return config;
      },
      async (error) => 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

    响应拦截器

    响应拦截器用于处理响应,包括处理错误和刷新令牌。以下是响应拦截器的示例代码:

    // 响应拦截器:用于处理响应
    instance.interceptors.response.use(
      (response: AxiosResponse) => {
        if (response.status === 204) {
          return response;
        }
    
        return response.data;
      },
      async (error: AxiosError) => {
        const { response } = error;
        if (response?.status === 401) {
          // 处理未授权 (401) 响应,重定向到登录页面
          const redirectUri = window.location.href;
          const loginUrl = `${LOGIN_URL}?${stringify({
            redirectUri,
          })}`;
          try {
            // 尝试无感刷新token
            const newAccessToken = await refreshAccessToken();
            setAccessToken(newAccessToken);
            const originalRequest = error.config;
            if (originalRequest) {
              originalRequest.headers.Authorization = `JWT ${newAccessToken}`;
              // 重新发送原始请求
              return axios(originalRequest);
            }
          } catch (refreshError) {
            removeAccessToken();
            let secondsToLogin: number = 5;
            const modal = Modal.error({
              title: '凭证失效',
              content: `你的登录凭证已失效,${secondsToLogin}s后将跳转到登录页面`,
              okText: '立即登录',
              okButtonProps: { disabled: true },
              onOk: () => {
                window.location.href = loginUrl;
              },
              afterClose: undefined,
            });
            const timer = setInterval(() => {
              secondsToLogin -= 1;
              modal.update({
                content: `你的登录凭证已失效,${secondsToLogin}s后将跳转到登录页面`,
                okButtonProps: { disabled: false },
                onOk: () => {
                  modal.destroy();
                  window.location.href = loginUrl;
                },
                afterClose: () => {
                  clearInterval(timer);
                },
              });
            }, 1000);
    
            setTimeout(() => {
              modal.destroy();
              clearInterval(timer);
              window.location.href = loginUrl;
            }, secondsToLogin * 1000);
          }
        } else {
          // 处理网络错误,显示通知
          notification.error({
            message: response?.status || '未知错误',
            description: response?.statusText || '系统错误,请联系管理员',
          });
        }
    
        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
    • 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
  • 相关阅读:
    包裹骨髓间充质干细胞/捕获内源性细胞因子的磺化/载有活性蛋白的壳聚糖水凝胶的制备与研究
    图解LeetCode——687. 最长同值路径(难度:中等)
    PodMan容器技术
    2023全球软件开发大会-上海站:探索技术前沿,共筑未来软件生态(附大会核心PPT下载)
    PDF文件转换为图片
    Trajectory Data Collection with Local Differential Privacy(论文翻译)
    戴尔Dell R740服务器开机冒烟亮黄灯故障维修
    基于Vue+Element UI+Node+MongoDB的医院门诊预约挂号系统
    计算机网络—交换机综合实验
    uniapp下拉框组件
  • 原文地址:https://blog.csdn.net/weixin_41908433/article/details/134211234