JS前端无侵入实现防止重复提交请求技术

最近在代码发布测试的过程中,我发现有些请求非常的消耗服务器资源,而系统测试人员因为响应太慢而不停的点击请求。我是很看不惯系统存在不顺眼的问题,做事喜欢精益求精,也很喜欢和别人争论技术,有时候硬要争得你死我活。

实在看不下去系统存在这个问题,下定决心好好整改一波,我们系统几乎都是使用Ajax技术发请求,使用的是针对我们系统特点对jQuery的post方法进行了封装的newpost方法,这个方法扩展了异常响应,登陆超时,token验证,加载时渲染等自动完成功能,参数不变,也是我写的。由于系统模块很多,功能很强大,代码也很多,为了统一使用此方法,花了不少时间将post修改成newpost。这次为了限制请求次数这个小功能,我请示了领导并把初步的方案说与他听,他同意了我做此次修改。

我调查了几个有防止请求重发控制的页面,几乎都是发起请求后到响应这段时间对按钮置灰警用处理,这种方案有很多的缺点,如:

1.         长时间未响应的请求给人不友好的体验

2.         需要针对每个按钮做请求前后的控制,会因为处理各种小问题而变得难以维护

3.         业务与控制逻辑混合在一起使得函数功能不单一

我最初的想法就是想找到一种类似于面向切面的无侵入页面的方式实现请求限制,因此想到了如下方案:

1.         只控制用户最后一次的请求

2.         第一次请求未响应之前一分钟之内不发相同的请求

3.         如果前一次请求得到了响应,那么第二次相同的请求也不做限制

后来发现这种方案行不通,主要有以下几个方面的原因:

1.         大多数页面每交互一次都会发起多个不同的请求。

2.         没个请求响应的时间也不一样,可能后发的请求先响应

我把这种想法告诉了导师,经过一番争论后认为我无法通过不侵入的方式实现这样的功能,按照他的想法,我得修改整个项目有请求的代码,完全低估了我对JS的了解,后来我独自优化了方案,不在只控制最后一个请求,代码实现的大纲如下:

发起POST请求前处理逻辑

1.         获取全局上下文中的存储请求信息的数组变量

2.         遍历请求响应数组

3.         清理大于两分钟未响应的请求,防止页面长时间不响应

4.         找到了与本次相同的请求

a)         如果请求小于200ms,则判断为系统行为,直接将环境和回调函数压入已有请求的调用栈,否则替换之前的请求的调用栈

b)        不发请求

5.         没有找到与本次相同的请求

a)         将请求信息、时间、调用环境和回调函数压进请求响应数组,请求URL和条件con作为唯一标识,调用栈也是一个由当前环境和回调函数组成的数组,使用数组解决相同的请求(url和con都一样)

b)        发起请求

请求响应后处理逻辑

1.         获取全局上下文中的存储请求信息的数组变量

2.         遍历请求响应数组

3.         找到了与此响应相同的请求

a)         遍历此请求的调用栈并依次调用回调函数

b)        删除已经处理的请求

4.         没有找到与此响应相同的请求则什么都不做

具体实现:

/*@description 自定义事件

 *@method_costomEvent

 *@formuphy

*/

muphypost: function (url, condition, callback, type, option) {

  if (typeof condition === 'function') {

       option = type;

       type = callback;

       callback = condition;

       condition = {};//jQuery:condition = undefine;

  }

  let that = this, reqUrl = (url + JSON.stringify(condition)).substr(0, 1000);

  //判断是否需要发起请求

  let hasReq = beforePost();

  if (hasReq === true) {

       return that;

  }

  //新增请求Token

  muphy.addToken(condition);

  //借助jQuery发请求

  $.post(url, condition, function (data, status){

       afterPost(data, status);

  }, type);

  return that;

  //请求前处理函数

  function beforePost() {

       //获取历史请求

       let postHistory = muphy.postHistory, now = new Date();

       //遍历请求响应数组,找到与此请求相同的请求

       for (let i = 0; i < postHistory.length;i++) {

           if (now - postHistory[i]._startTime > 120000) {

               //清理大于两分钟未响应的请求

               postHistory.splice(i, 1);

           } elseif (postHistory[i]._reqUrl === reqUrl){

               //找到了就更新请求时间,并将执行环境和回调函数放入请求响应数组的调用栈;

               //小于200ms判定为系统行为直接将环境和回调函数压入已有请求的调用栈,

//否则替换之前的请求

               if (now - postHistory[i]._startTime < 200) {

                   postHistory[i]._startTime =now;

                  postHistory[i]._handles.push({ _callback: callback, _this: that });

               } else {

                   postHistory[i]._handles =[{ _callback: callback, _this: that }];

               }

               //返回true 表示本次不发请求

               return true;

           }

       };

      //没找到与此相同的请求时将请求信息、时间、调用环境和回调函数压进请求响应数组

       postHistory.push({ _reqUrl: reqUrl,_startTime: new Date(), _handles: [{ _callback:callback, _this: that }] });

       //返回false 表示本次需要发请求

       return false;

  }

  //请求后处理函数

  function afterPost(data, status) {

       //获取请求响应数组

       let postHistory = muphy.postHistory;

       //遍历请求响应数组,找到与此请求相同的请求

       for (let i = 0; i < postHistory.length;i++) {

           if (postHistory[i]._reqUrl === reqUrl) {

               //找到相同的请求,遍历此请求的调用栈并调用

              muphy.each(postHistory[i]._handles, function () {

                   this._callback.call(this._this, data, status);

               });

               //调用完成删除已经处理的请求

               postHistory.splice(i, 1);

               break;

           }

       }

  }

}

JS前端无侵入实现防止重复提交请求技术的更多相关文章

  1. ajax防止重复提交请求1

    ajax防止重复提交请求 A. 独占型提交 只允许同时存在一次提交操作,并且直到本次提交完成才能进行下一次提交. module.submit = function() {   if (this.pro ...

  2. JS中如何防止表单重复提交问题

    在登录页面html中写如下代码 <script type="text/javascript"> var issubmit=false; function dosubmi ...

  3. 使用js是想防止表单重复提交的效果

    直接上代码: <html> <head> <title>Form表单</title> <script type="text/javasc ...

  4. js 前端向服务器端传送文件的常用请求方式

    在做项目的过程当中写到文件上传的功能,想着之前也是踩坑过来的,就在这里总结下自己常用的方法吧.我们现在一般都是通过ajax来搭起前后端数据交互的桥梁,但是大家在做到有文件需要上传的时候就会发现我们用a ...

  5. java web解决表单重复提交问题

    我们大家再进行web开发的时候,必不可少会遇见表单重复提交问题.今天就来给总结如何解决表单提交问题,欢迎大家交流指正. 首先我们在讨论如何解决表单重复提交问题之前先来解决三个问题:1.什么叫表单重复提 ...

  6. java web解决表单重复提交

    首先我们在讨论如何解决表单重复提交问题之前先来解决三个问题:1.什么叫表单重复提交?2.什么情况下会出现表单重复提交?3.什么情况需要避免表单重复提交? 什么叫表单提交问题,说白了,就是同一份信息,重 ...

  7. php解决表单重复提交

    php解决表单重复提交时间:2015-2-28 | 评论:1条评论 | 被查看了 189 次 | 标签:php, W3cui重复提交是我们开发中会常碰到的一个问题,除了我们使用js来防止表单的重复提交 ...

  8. PHP防止表单重复提交的解决方法

    PHP+SESSION防止表单重复提交 index.php 当前表单页面is_submit设为0 SESSION_START(); $_SESSION['is_submit'] = 0; <fo ...

  9. php 解决表单重复提交实现方法介绍

    重复提交是我们开发中会常碰到的一个问题,除了我们使用js来防止表单的重复提交,同时还可以使用php来防止重复提交哦. 例1  代码如下 复制代码 <?php/* * php中如何防止表单的重复提 ...

随机推荐

  1. 一次node-sass安装记录

    node-sass的版本是3.9.3 Please restart this script from an administrative PowerShell! 在当前powershell中执行下命令 ...

  2. MySQL 笔记整理(18) --为什么这些SQL语句逻辑相同,性能却差异巨大?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 18) --为什么这些SQL语句逻辑相同,性能却差异巨大? 本篇我们以三 ...

  3. Can`tconnect to MySQL server on 'localhost'(10061)问题解决

    今天在登陆MySQL是登录不上出现了“Can`tconnect to MySQL server on ‘localhost’(10061)”的问题,于是便在网上到处搜资料查原因:但好多都是:让删除my ...

  4. web服务器负载均衡与集群基本概念一

    Web集群是由多个同时运行同一个web应用的服务器组成,在外界看来就像一个服务器一样,这多台服务器共同来为客户提供更高性能的服务.集群更标准的定义是:一组相互独立的服务器在网络中表现为单一的系统,并以 ...

  5. weblogic doc

    BEA WebLogic Server 9.2 Documentation https://docs.oracle.com/cd/E13222_01/wls/docs92/index.html 8.1 ...

  6. Python 经典面试题汇总之数据库篇

    数据库和缓存 1.列举常见的关系型数据库和非关系型都有那些? 关系型数据库(需要有表结构) mysql.oracle.splserver.postgresql.db2.sybase 非关系型数据库(是 ...

  7. 阿里云服务器部署Java Web项目全过程

    最近需要将一个Java Web项目部署到服务器上,方便多人共享访问.这也是我第一次接触服务器之类的东西,也花了一点时间,最终总算部署成功,写下一篇文章记录以便日后回顾. 购买服务器 第一步当然是需要购 ...

  8. win10安装spacemacs

    参考: https://www.cnblogs.com/e190/p/10404927.html https://blog.csdn.net/u011729865/article/details/54 ...

  9. Scrapy框架-Spider

    目录 1. Spider 2.Scrapy源代码 2.1. Scrapy主要属性和方法 3.parse()方法的工作机制 1. Spider Spider类定义了如何爬取某个(或某些)网站.包括了爬取 ...

  10. matlab导入txt数据画图

    因为最近需要观察txt保存的一堆数据,则需要使用这些数据画图.强大的matlab分分钟解决了. 实例数据:data.txt 步骤: ①打开matlab -> HOME(主页) -> Imp ...