防ajax重复提交

    经常在工作中测试人员发现一些重复提交的问题,js的ajax重复提交尤为常见(几乎全是)。虽然处理办法有多种,但一般都只是前台js做处理。且这种处理对于个要数据提交处都要做逻辑判断来去防止,如果有多处这种请求不仅工作量大且而且不利于统一管理。

 

    介绍一种处理这种问题的一个办法,虽不是最好最简结的但算是比较好管理且减少工作量的。

 

         1,首先js上做下规范,发送ajax请求可用同一包装方法。这样比较容易对js请求做统一处理,即使有改动也不必要去每处发送请求的地方去查找。

 

myAjaxs = {
        /*
         * 请求获取后台数据统一调用
         * @param {object} param{
         *                      type    : '', get/post
         *                      url     : '', 请求URL
         *                      dataType: '', json或其他
         *                      data    : {}, 参数
         *                      succFun : function(){}, 成功回调函数
         *                      errFun  : function(){}  失败回调函数
         *                 }
         */
        ajax  :  function(param){
            if(!param){
                return;
            }
            var params = {
                type        : 'post',
                dataType    : 'json',
                data        : {'token' : token , 'date':new Date().getTime()}
            };
            $.extend(params,param);
            var obj = {};
            obj.url = params.url;
            obj.type = params.type;
            obj.dataType = params.dataType;
            obj.data = params.data;
            obj.complete = function(XMLHttpRequest, textStatus){
            	//这里请求完成后回调函数 (请求成功或失败时均调用),
            	//所以我们这里来做防止重复ajax提交当然也可放在成功能回调里去做   上面传参 'token' : token
            	//这里的token设为一个全部变量用于保存后台传过来的
            	//当后台有token传过来就覆新值否则不变
            	token = XMLHttpRequest.token || token;
           }
            if(param.succFun){
                obj.success = function(json){
                    //你要处理的逻辑
                    param.succFun.apply(null,[params,resjson]);
                };            
            }
            if(params.errFun){
                obj.error = function(request, textStatus, errorThrown){
                	 //你要处理的逻辑
                    param.errFun.apply(null,[request,textStatus,errorThrown,params]);
                };
            }
            return $.ajax(obj); 
        }
    };
    

 

 

 

    2,后台java处理,这里要使用到拦截器(工程中没用到struts的可以用过滤器去实现)。建一个方法拦截器类,这拦截器配制只拦截你所要拦截的方法(有ajax数据提交的方法),当然也可以自己去指定那些特定action用这个拦截器。在拦截器里面我们要做一个token处理,类似struts自带的token防页面重复提交。

 

@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpSession session = request.getSession();
		// 生成一个随机码,用作防止重复提交
		String newToken = String.valueOf(System.currentTimeMillis());
		String requetToken = request.getParameter("token");
		Object token = session.getAttribute("ajax_token");
		String retStr;
		
		if(token == null){
			session.setAttribute("ajax_token", newToken);
			retStr = print("{\"token\" :" +  newToken },invocation);
		}else if(requetToken.equals(token.toString())){
                       session.setAttribute("ajax_token", newToken);
                       retStr = print("{\"token\" :" +  newToken ,invocation);
		}else{
			retStr = Action.SUCCESS;
		}
		
		return retStr;
	}

private String print(String msg,ActionInvocation invocation) throws IOException{
		HttpServletResponse response = ServletActionContext.getResponse();
	    PrintWriter out = response.getWriter();
	    out.print(msg);
	    out.flush();
	    out.close();
	    
	    return invocation.invoke();
	}


/*这种方法实现也存在着问题,如果可以提交后要反回一些json数据从action那里,而这种改变不了action json的值只能覆盖,所以也不通用。同时还存在着由于网络原因或是其它导致token从服务器端传不到js回调函数中的原因,导致请求都不能提交。大家可以根据自己项目中实现问题再去小小改动*/
 
避免AJAX重复提交通常是为了止用户在同一时间无意间多次触发某个操作,比如表单提交或者数据更新。这不仅可能导致服务器资源浪费,还可能带来用户体验的问题,例如在加载过程中多次刷新页面。以下是几种常用的方法来避免AJAX重复提交: 1. **添加全局抖动或节流**(Debounce或Throttle): - **抖**:当用户连续快速触发某个事件时,只有最后一次触发才执行对应的AJAX请求。一旦用户停止输入,函数会等待一段时间后再执行,止短时间内多次提交。 - **节流**:无论用户如何频繁触发,都只会执行一次请求。通常设定一个固定的时间间隔,如果在这段时间内又有新的触发,那么当前的请求会被取消,直到下一次节流周期结束。 2. **在发起请求前禁用按钮**: 将表单提交按钮或其他触发动作的元素设置为`disabled`状态,直到AJAX请求完成再将其恢复原状。这样用户就不能再次点击它。 3. **利用事件委托**: 对于动态生成的元素,通过事件代理来监听提交事件。这样可以确保不论何时表单提交都是在一个统一的地方处理,避免了因元素添加或移除而产生的重复绑定。 4. **设置提交标志或锁定状态**: 为表单添加一个状态标志,如`formSubmitting`,在开始AJAX请求时置为true,完成后恢复为false。这样,在提交期间不允许再次触发表单的提交事件。 5. **校验前端验证**: 提交之前先在客户端做初步的验证,只有在所有验证通过的情况下才发送AJAX请求。如果前端验证失败,就阻止提交并给出提示,无需发送请求。 6. **服务器端校验**: 服务器也可以验证同一时间是否有重复提交。例如,设置一个token并在客户端和服务器端都保存,只有第一次提交时有效的token才会被执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值