/src/utils/request.ts:axios 请求封装,适用于需要统一处理请求和响应的场景

news2025/1/10 18:10:28

文章目录

      • 数据结构解释
      • 1. 核心功能
      • 2. 代码结构分析
        • 请求拦截器
        • 响应拦截器
      • 3. 改进建议
      • 4. 总结

console.log('Intercepted Response:', JSON.stringify(response));
{
  "data": {
    "code": 0,
    "msg": "成功",
    "data": {
      "id": 76,
      "inviteCode": "957989",
      "invitorId": 56,
      "remark": "测试",
      "generatedDate": "2025-01-08T16:55:27.163",
      "expireTime": "2025-01-15T16:55:27.163",
      "inviteLevel": 2,
      "status": 0,
      "boundPhone": null,
      "weixinNickname": null,
      "weixinHeadimg": null,
      "boundWxUid": null,
      "adminId": null,
      "userId": null,
      "isLocked": 0,
      "createdDate": "2025-01-08T16:55:27.163",
      "lastModifiedDate": "2025-01-08T16:55:27.163"
    }
  },
  "status": 200,
  "statusText": "",
  "headers": {
    "cache-control": "no-cache, no-store, max-age=0, must-revalidate",
    "content-type": "application/json;charset=UTF-8",
    "expires": "0",
    "pragma": "no-cache"
  },
  "config": {
    "url": "/api/invite-codes/generate",
    "method": "post",
    "params": {
      "invitorId": 56,
      "remark": "测试"
    },
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI1NiIsInJvbGUiOiJST0xFX0NPTVBBTllfU1VQRVIiLCJleHAiOjE3MzY0MDA5MDMsInVzZXJOYW1lIjoiMTg2NjE5Nzc1ODEiLCJ0eXBlIjoiYWRtaW4iLCJpYXQiOjE3MzYzMTQ1MDN9.OBFnxtoE4A2RO6gAcVm_CUkvJl_j6wpUkOPZOZySwEk"
    },
    "baseURL": "http://127.0.0.1:8087/",
    "transformRequest": [null],
    "transformResponse": [null],
    "timeout": 0,
    "withCredentials": false,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1
  },
  "request": {}
}

数据结构解释

  • data: 包含实际业务响应数据,其中:
    • code: 响应码,0 表示成功。
    • msg: 响应消息。
    • data: 具体数据,包括邀请码的详细信息。
  • status: HTTP 状态码,200 表示请求成功。
  • headers: 响应头信息。
  • config: 请求配置详情,包括 URL、请求方法、参数、头部信息等。
  • request: 请求对象,具体内容在此为空。

如需对其中的字段进行详细解析,请告知我! 😊

// spid-admin/src/utils/request.ts
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import { UserModule } from '@/store/modules/user'
import { api } from '@/utils/public-path'

let logoutCount:number = 0
const service = axios.create({
  baseURL: api, // url = base url + request url
  timeout: 0,
  withCredentials: false // send cookies when cross-domain requests
})

// Request interceptors
service.interceptors.request.use(
  (config) => {
    // Add X-Access-Token header to every request, you can add other custom headers here
    if (UserModule.token) {
      const { token }: any = JSON.parse(UserModule.token)
      config.headers['token'] = token
    }
    //console.log('Request config:', config); // 添加这行代码
    return config
  },
  (error) => {
    Promise.reject(error)
  }
)

// Response interceptors
service.interceptors.response.use(
  (response) => {
    //console.log('Intercepted Response:', JSON.stringify(response));
    //console.log('Full Response Data:', JSON.stringify(response, null, 2));
    // Some example codes here:
    // You can change this part for your own usage.
    // status == 200: success
    // code === 0: success
    // code === 1: invalid access token

    const res = response.data
    if (res.code !== 0) {
      if (res.code === 1) {
        Message({
          message: res.msg || 'Error',
          type: 'warning',
          duration: 5 * 1000
        })
        return response.data
      } else if (res.code === 7) {
        MessageBox.confirm(
          '你已被登出,可以取消继续留在该页面,或者重新登录',
          '确定登出',
          {
            confirmButtonText: '重新登录',
            cancelButtonText: '取消',
            type: 'warning'
          }
        ).then(() => {
          logoutCount = 0
          localStorage.clear()
          sessionStorage.clear()
          UserModule.ResetToken()
          location.reload() // To prevent bugs from vue-router
        })
      } else if (res.indexOf('form') !== -1) {
        // 支付宝支付 ....... 为什么不改造成正常接口呢 不理解
        return Promise.resolve(res)
      } else {
        Message({
          message: res.msg || 'Error',
          type: 'error',
          duration: 5 * 1000
        })
        return Promise.reject(new Error(res.msg || 'Error'))
      }
    } else {
      return response.data
    }
  },
  (error) => {
    console.log(error)
    let errorInfo = error.response
    let msg
    if (!errorInfo) {
      const { request: { statusText, status }, config } = JSON.parse(JSON.stringify(error))
      errorInfo = {
        statusText,
        status,
        request: { responseURL: config.url }
      }
      msg = status + ':' + errorInfo.statusText
    } else {
      if (error.response.data.code === -1) {
        if (logoutCount === 0) {
          MessageBox.confirm(
            '你已被登出,可以取消继续留在该页面,或者重新登录',
            '确定登出',
            {
              confirmButtonText: '重新登录',
              cancelButtonText: '取消',
              type: 'warning'
            }
          ).then(() => {
            logoutCount = 0
            localStorage.clear()
            sessionStorage.clear()
            UserModule.ResetToken()
            location.reload() // To prevent bugs from vue-router
            msg = error.response.data.msg
          })
          logoutCount++
          return
        }
      } else if (errorInfo.data.code === 1 || errorInfo.data.code === 2) {
        msg = errorInfo.data.msg
      } else {
        msg = error.response.data.status + ':' + error.response.data.message
      }
    }
    Message({
      message: msg,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(msg)
  }
)

export default service

这段代码是一个基于 axios 的请求封装,主要用于处理 HTTP 请求的拦截和响应拦截。它结合了 Element UI 的消息提示和弹窗组件,实现了以下功能:


1. 核心功能

  • 请求拦截
    • 在请求发送之前,检查用户是否已登录(通过 UserModule.token)。
    • 如果用户已登录,将 token 添加到请求头中。
  • 响应拦截
    • 对响应数据进行统一处理,根据返回的 code 值判断请求是否成功。
    • 处理特定的错误码(如 code === 1code === 7),并显示相应的提示信息。
    • 在用户登录状态失效时,弹出确认框提示用户重新登录。

2. 代码结构分析

请求拦截器
service.interceptors.request.use(
  (config) => {
    if (UserModule.token) {
      const { token }: any = JSON.parse(UserModule.token);
      config.headers['token'] = token;
    }
    return config;
  },
  (error) => {
    Promise.reject(error);
  }
);
  • 功能
    • 在每次请求发送之前,检查用户是否已登录。
    • 如果已登录,将 token 添加到请求头中。
  • 注意
    • UserModule.token 是从 Vuex 模块中获取的,需要确保 UserModule 已正确初始化。

响应拦截器
service.interceptors.response.use(
  (response) => {
    const res = response.data;
    if (res.code !== 0) {
      if (res.code === 1) {
        Message({
          message: res.msg || 'Error',
          type: 'warning',
          duration: 5 * 1000,
        });
        return response.data;
      } else if (res.code === 7) {
        MessageBox.confirm(
          '你已被登出,可以取消继续留在该页面,或者重新登录',
          '确定登出',
          {
            confirmButtonText: '重新登录',
            cancelButtonText: '取消',
            type: 'warning',
          }
        ).then(() => {
          logoutCount = 0;
          localStorage.clear();
          sessionStorage.clear();
          UserModule.ResetToken();
          location.reload(); // To prevent bugs from vue-router
        });
      } else if (res.indexOf('form') !== -1) {
        // 支付宝支付 ....... 为什么不改造成正常接口呢 不理解
        return Promise.resolve(res);
      } else {
        Message({
          message: res.msg || 'Error',
          type: 'error',
          duration: 5 * 1000,
        });
        return Promise.reject(new Error(res.msg || 'Error'));
      }
    } else {
      return response.data;
    }
  },
  (error) => {
    console.log(error);
    let errorInfo = error.response;
    let msg;
    if (!errorInfo) {
      const { request: { statusText, status }, config } = JSON.parse(JSON.stringify(error));
      errorInfo = {
        statusText,
        status,
        request: { responseURL: config.url },
      };
      msg = status + ':' + errorInfo.statusText;
    } else {
      if (error.response.data.code === -1) {
        if (logoutCount === 0) {
          MessageBox.confirm(
            '你已被登出,可以取消继续留在该页面,或者重新登录',
            '确定登出',
            {
              confirmButtonText: '重新登录',
              cancelButtonText: '取消',
              type: 'warning',
            }
          ).then(() => {
            logoutCount = 0;
            localStorage.clear();
            sessionStorage.clear();
            UserModule.ResetToken();
            location.reload(); // To prevent bugs from vue-router
            msg = error.response.data.msg;
          });
          logoutCount++;
          return;
        }
      } else if (errorInfo.data.code === 1 || errorInfo.data.code === 2) {
        msg = errorInfo.data.msg;
      } else {
        msg = error.response.data.status + ':' + error.response.data.message;
      }
    }
    Message({
      message: msg,
      type: 'error',
      duration: 5 * 1000,
    });
    return Promise.reject(msg);
  }
);
  • 功能
    • 对响应数据进行统一处理。
    • 根据返回的 code 值判断请求是否成功,并显示相应的提示信息。
    • 处理特定的错误码(如 code === 1code === 7),并在用户登录状态失效时弹出确认框提示用户重新登录。
  • 注意
    • code === 7 表示用户登录状态失效,会清除本地存储并刷新页面。
    • code === 1 表示请求失败,会显示警告信息。
    • 其他错误码会显示错误信息。

3. 改进建议

  • 支付宝支付逻辑
    • 代码中提到 res.indexOf('form') !== -1 是处理支付宝支付的逻辑,但注释中提到“为什么不改造成正常接口呢 不理解”。建议将支付宝支付逻辑改造为标准的接口返回格式,以便统一处理。
  • 错误处理
    • error.response 为空时,手动构造错误信息。可以考虑使用更健壮的方式处理网络错误。
  • logoutCount 的作用
    • logoutCount 用于防止多次弹出登录失效的确认框。可以考虑使用更优雅的方式实现,例如在 Vuex 中维护登录状态。

4. 总结

这段代码是一个典型的 axios 请求封装,适用于需要统一处理请求和响应的场景。它结合了 Element UI 的消息提示和弹窗组件,提供了良好的用户体验。通过进一步优化错误处理和逻辑封装,可以提高代码的可维护性和健壮性。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2274477.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu24.04安装AppImage报错AppImages require FUSE to run.

报错如下: 解决: sudo apt install libfuse2t64如果不行: sudo add-apt-repository universe sudo apt install libfuse2t64安装时又报错: [10354:0109/100149.571068:FATAL:setuid_sandbox_host.cc(158)] The SUID sandbox hel…

2025新春烟花代码(二)HTML5实现孔明灯和烟花效果

效果展示 源代码 <!DOCTYPE html> <html lang"en"> <script>var _hmt _hmt || [];(function () {var hm document.createElement("script");hm.src "https://hm.baidu.com/hm.js?45f95f1bfde85c7777c3d1157e8c2d34";var …

同步整流 MT6705 应用注意事项

MT6705 是用于反激式变换器的高性能45V 同步整流器。它兼容各种反激转换器类型。支持 DCM、CCM 和准谐振模式。MT6705集成了一个40V功率MOSFET&#xff0c;可以取代肖特基二极管&#xff0c;提高效率。MT6705 PCB 布局应遵循以下规则: 1、VCC 电容器: VCC 引脚必须放置电容,电容…

LLaMA-Factory web微调大模型并导出大模型

LLaMA-Factory 开源大模型如LLaMA&#xff0c;Qwen&#xff0c;Baichuan等主要都是使用通用数据进行训练而来&#xff0c;其对于不同下游的使用场景和垂直领域的效果有待进一步提升&#xff0c;衍生出了微调训练相关的需求&#xff0c;包含预训练&#xff08;pt&#xff09;&am…

Jenkins内修改allure报告名称

背景&#xff1a; 最近使用Jenkins搭建自动化测试环境时&#xff0c;使用Jenkins的allure插件生成的报告&#xff0c;一直显示默认ALLURE REPORT&#xff0c;想自定义成与项目关联的名称&#xff0c;如图所示&#xff0c;很明显自定义名称显得高大上些&#xff0c;之前…

RK3588平台开发系列讲解(系统篇)Linux Kconfig的语法

文章目录 一、什么是Kconfig二、config模块三、menuconfig四、menu 和 endmenu五、choice 和 endchoice六、source七、depends on八、default九、help十、逻辑表达式沉淀、分享、成长,让自己和他人都能有所收获!😄 一、什么是Kconfig Kconfig的语法及代码结构非常简单。本博…

Android原生开发同一局域网内利用socket通信进行数据传输

1、数据接收端代码如下&#xff0c;注意&#xff1a;socket 接收信息需要异步运行&#xff1a; // port 端口号自定义一个值&#xff0c;比如 8888&#xff0c;但需和发送端使用的端口号保持一致 ServerSocket serverSocket new ServerSocket(port); while (true) {//这里为了…

Elasticsearch学习(1) : 简介、索引库操作、文档操作、RestAPI、RestClient操作

目录 1.elasticsearch简介1.1.了解es1.2.倒排索引正向索引和倒排索引 1.3.es的一些概念:文档和字段&#xff1b;索引和映射&#xff1b;Mysql与ES1.4.安装es、kibana部署单点es部署kibanaIK分词器安装IK分词器与测试扩展与停用词词典总结 部署es集群 2.索引库操作2.1.mapping映…

Clickhouse基础(一)

操作命令&#xff1a; sudo clickhouse start sudo clickhouse restart sudo clickhouse status进入clickhouse clickhouse-client -mCREATE TABLE db_13.t_assist (modelId UInt64,taskId UInt64,testNo String,tdId UInt64,eventDay String,eventDaytime UInt64,eventBatch …

记录将springboot的jar包和lib分离,使用docker-compose部署

本文讲诉如何把jar里的lib依赖包独立出来&#xff0c;方便更新服务时&#xff0c;缩小jar的体积&#xff0c;下面以若依的system服务为例&#xff0c;配置中的路径请酌情修改&#xff0c;主要提供大致配置逻辑 第一步&#xff1a;修改项目的pom.xml&#xff0c;调整build的配…

【对象存储】-- s3:\\、s3n:\\、s3a:\\ 简介

目录 1. s3:\ 2. s3n:\ 3. s3a:\ 区别对比 总结 在 Hadoop 和大数据处理领域&#xff0c;s3:\\、s3n:\\ 和 s3a:\\ 是访问 Amazon S3 的不同文件系统实现方式。以下是它们的简要介绍、区别及应用场景&#xff1a; 1. s3:\ 全称&#xff1a;Hadoop S3 Native FileSystem。…

Springboot3.x工程创建及必要引用(基础篇)

下面从环境的安装和配置开始&#xff0c;到Springboot3.x工程创建&#xff0c;记录一下让完全没有基础的小白用户也能够开始自己的第一个项目。 准备 安装JDK环境&#xff08;这里最好安装JDK17及以上版本&#xff09;安装IntelliJ IDEA Ultimate工具&#xff08;可以从官网下…

腾讯云AI代码助手-公司职位分析AI助手

作品简介 腾讯云AI代码助手是一款智能工具&#xff0c;专注于为公司提供职位分析服务。通过自然语言处理和机器学习技术&#xff0c;它能快速解析职位描述&#xff0c;提取关键信息&#xff0c;并提供数据驱动的洞察&#xff0c;帮助公司优化招聘流程和职位设计。 技术架构 …

QML学习(八) Quick中的基础组件:Item,Rectangle,MouseArea说明及使用场景和使用方法

上一篇中我们从设计器里可以看到Qt Quick-Base中有几大基础组件&#xff0c;如下图&#xff0c;这篇文章先介绍下Item&#xff0c;Rectangle&#xff0c;MouseArea这三个的说明及使用场景和使用方法 Item Item 是 QML 中所有可视元素的基类&#xff0c;是一个非常基础和通用的…

宇航用VIRTEX5系列FPGA的动态刷新方法及实现

SRAM型FPGA在宇航领域有广泛的应用&#xff0c;为解决FPGA在空间环境中的单粒子翻转问题&#xff0c;增强设计的可靠性&#xff0c;本文介绍一种低成本的抗辐照解决方案。该方案从外置高可靠存储器中读取配置数据&#xff0c;通过定时刷新结合三模冗余的方式消除单粒子影响&…

03.MPLS静态LSP配置实验

MPLS静态LSP配置实验 1、实验环境2、基础配置开启全局mpls接口下开启mpls配置静态LSP配置FEC从1.1.1.1到3.3.3.3配置FEC从3.3.3.3到1.1.1.13、信息查看查看LFIB表(标签转发信息表)查看FIB表(转发信息表)查看详细FFIB表tracert lsp iptracert -vping lsp ip4、抓包验证1、实…

el-table表格合并某一列

需求&#xff1a;按照下图完成单元格合并&#xff0c;数据展示 可以看到科室列是需要合并的 并加背景色展示&#xff1b;具体代码如下&#xff1a; <el-tableref"tableA":data"tableDataList":header-cell-style"{ backgroundColor: #f2dcdb, col…

PostgreSQL学习笔记(二):PostgreSQL基本操作

PostgreSQL 是一个功能强大的开源关系型数据库管理系统 (RDBMS)&#xff0c;支持标准的 SQL 语法&#xff0c;并扩展了许多功能强大的操作语法. 数据类型 数值类型 数据类型描述存储大小示例值SMALLINT小范围整数&#xff0c;范围&#xff1a;-32,768 到 32,7672 字节-123INTE…

javaEE-网络编程4.TCP回显服务器

目录 TCP流套接字编程 一.API介绍 ServerSocket类 构造方法&#xff1a; ​编辑方法&#xff1a; Socket类 构造方法&#xff1a; 方法&#xff1a; 二、TCP连接 三、通过TCP实现回显服务器 TCP服务端&#xff1a; 1.创建Socket对象 2.构造方法 3.start方法 TCP客…

RIS智能无线电反射面:原理、应用与MATLAB代码示例

一、引言 随着无线通信技术的快速发展,人们对通信系统的容量、覆盖范围、能效以及安全性等方面的要求日益提高。传统的无线通信系统主要通过增加基站数量、提高发射功率和优化天线阵列等方式来提升性能,但这些方法面临着资源有限、能耗高和成本上升等挑战。因此,探索新的无线…