当前位置: 首页 > article >正文

ruoyi-vue若依前端是如何防止接口重复请求

防止接口重复请求是为了避免用户在短时间内多次点击同一个按钮,导致后端接口被多次调用,引发数据异常或性能问题。
之前的文章介绍过后端如何防止接口重复请求,这篇文章介绍一下前端如何防止接口重复提交。

按钮禁用

用户点击按钮后立即将按钮设置为禁用状态,待接口返回结果或一段时间后再恢复按钮可用。这样可以有效防止用户在请求未完成时重复点击。

const submitForm = () => {
       if (!buttonDisabled) {
         buttonDisabled = true;
         axios.post('/api/submit', data)
           .then(response => {
             // 请求成功
           })
           .catch(error => {
             // 错误处理
           })
           .finally(() => {
             // 恢复按钮状态
             buttonDisabled = false;
           });
       }
     }

请求拦截器

以下是若依源码:

// request拦截器
service.interceptors.request.use(config => {
  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  // 是否需要防止数据重复提交
  const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  if (getToken() && !isToken) {
    config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  }
  // get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?' + tansParams(config.params);
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }
  if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
    const requestObj = {
      url: config.url,
      data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
      time: new Date().getTime()
    }
    const sessionObj = cache.session.getJSON('sessionObj')
    if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
      cache.session.setJSON('sessionObj', requestObj)
    } else {
      const s_url = sessionObj.url;                // 请求地址
      const s_data = sessionObj.data;              // 请求数据
      const s_time = sessionObj.time;              // 请求时间
      const interval = 1000;                       // 间隔时间(ms),小于此时间视为重复提交
      if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
        const message = '数据正在处理,请勿重复提交';
        console.warn(`[${s_url}]: ` + message)
        return Promise.reject(new Error(message))
      } else {
        cache.session.setJSON('sessionObj', requestObj)
      }
    }
  }
  return config
}, error => {
    Promise.reject(error)
})

这段代码是一个请求拦截器,用于拦截发送的HTTP请求,并对请求进行一些预处理操作,主要包括Token注入防止重复提交的功能。以下是代码的具体作用:

1. Token设置

const isToken = (config.headers || {}).isToken === false;
if (getToken() && !isToken) {
  config.headers['Authorization'] = 'Bearer ' + getToken(); 
}
  • 作用:检查当前请求是否需要携带Token。通过config.headers.isToken字段决定,若isTokenfalse,表示不需要携带Token,否则会将Authorization头设置为带有Bearer前缀的Token。
  • 逻辑getToken()用于获取存储的Token(比如从cookie或localStorage中),并在请求头中注入Authorization,这样后端能够识别用户身份。

2. GET请求参数处理

if (config.method === 'get' && config.params) {
  let url = config.url + '?' + tansParams(config.params);
  url = url.slice(0, -1);
  config.params = {};
  config.url = url;
}
  • 作用:对于GET请求,将params参数序列化并拼接到URL中。
  • 逻辑:如果请求是GET方法,并且存在params参数,那么它会将这些参数通过tansParams方法(通常是将参数对象转为key=value形式的字符串)拼接到URL后面。最后清空config.params,并将新的URL赋值给config.url

3. 防止重复提交

const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
  const requestObj = {
    url: config.url,
    data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
    time: new Date().getTime()
  }
  const sessionObj = cache.session.getJSON('sessionObj');
  if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
    cache.session.setJSON('sessionObj', requestObj);
  } else {
    const s_url = sessionObj.url;
    const s_data = sessionObj.data;
    const s_time = sessionObj.time;
    const interval = 1000;
    if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
      const message = '数据正在处理,请勿重复提交';
      console.warn(`[${s_url}]: ` + message);
      return Promise.reject(new Error(message));
    } else {
      cache.session.setJSON('sessionObj', requestObj);
    }
  }
}
  • 作用:用于防止短时间内重复提交相同的POST或PUT请求。
  • 逻辑
    1. 通过检查config.headers.repeatSubmit字段判断是否启用防重复提交(false表示不启用防重)。
    2. 对于需要防止重复提交的请求(POST或PUT方法),会将请求的urldata和当前时间time封装为requestObj对象。
    3. 读取会话缓存中的上一次请求对象(sessionObj),如果不存在,则将当前请求对象保存到会话缓存中。
    4. 如果上一次请求的urldata和当前请求相同,且两次请求时间间隔小于1秒钟(interval = 1000),则视为重复提交,拦截请求并返回错误信息。
    5. 否则,将当前请求对象更新到缓存中,允许请求继续发送。

http://www.kler.cn/news/316643.html

相关文章:

  • 计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-19
  • 【Linux 20】线程控制
  • Facebook开发者篇 - API拉取广告投放数据对接流程
  • D. Minimize the Difference (Codeforces Round 973 Div. 2)
  • 【人工智能学习笔记】7_智能语音技术基础
  • 【自定义函数】讲解
  • 香港科技大学广州|金融科技学域博士招生宣讲会——武汉大学、华中科技大学
  • 【算法】遗传算法
  • go语言基础入门(一)
  • 安全带检测系统源码分享
  • ArcGIS Pro SDK (十六)公共设施网络 2 网络图
  • MySQL篇(高级字符串函数/正则表达式)(持续更新迭代)
  • Web端云剪辑解决方案,BS架构私有化部署,安全可控
  • 【ARM】A64指令介绍及内存屏障和寄存器
  • 借用连接1-怎么从目标数据源借用连接
  • 【题解-力扣189. 轮转数组(java实现O(1)空间要求)】
  • Python3爬虫教程-HTTP基本原理
  • 数据结构--单链表创建、增删改查功能以及与结构体合用
  • Java 入门指南:JVM(Java虚拟机)—— 双亲委派模型(Parent Delegation Model)
  • 2024短剧系统开发,付费短剧小程序app源码教程,分销功能讲解搭建上线
  • 【UI自动化】前言
  • 服务器相关问题
  • 机器学习及其应用领域【金融领域】
  • css 控制虚线刻度尺寸
  • 【手写数据库内核组件】1001词法分析器,语言被程序识别的第一步,将语句分解为最小词根token
  • Qt 模型视图(二):模型类QAbstractItemModel
  • 可智能生成刺绣图案!武汉纺织大学可视计算与数字纺织团队发布首个多缝线刺绣生成对抗网络模型,被顶级期刊 TVCG 录用
  • 后端开发刷题 | 最长无重复子数组
  • ArcGIS Pro SDK (十六)公共设施网络 1 网络管理
  • 人工智能与机器学习原理精解【22】