js asynchronous ajax implementation to avoid repeated page submission

1 ajax overview

The difference between ajax synchronous and asynchronous is:

  • Synchronization is basically performed in sequence. For this reason, during the transmission of data, the browser has been in a waiting state. If the amount of data is too large or the network speed is too slow, a suspended animation will occur (this content is in the author's previous blog post <Asynchronous Ajax Implementation) Sequential execution> is also proposed), so contemporary ajax basically no longer uses synchronous configuration;
  • Asynchronous is what to do next after sending, similar to the relationship between the continuously dispatched scouts and the normal army marching during the march. It is just that sometimes the information of some scouts is more important. Before the army or the next scout is dispatched, it must be Once you get the information of these scouts, you can go down. Various possible problems are derived from this, and one of the problems that newcomers often encounter is: repeated submissions caused by the continuous triggering of the same event .

2 Problem description

It should be noted that repeated submission has different solutions for different situations. The method described in this article is mainly aimed at the user's false repeated triggering of the same event
under normal use . For example, for a button, because the mouse is not easy to use Or new users do not understand, click more than two times in a row. In this case, it can be solved from the js design of the page ; corresponding to the normal usage, it is an abnormal situation, such as some users maliciously and frequently send requests to obtain For the user login information of a website, this kind of problem must be solved by interacting with the background, which is not within the scope of this article ; the following situations discuss possible problems:

  • For get requests , there are often no bad effects. At most, it just wastes network bandwidth and slightly increases server pressure. For example, querying the same product list twice is just a waste of time;
  • For post requests , repeated triggering is likely to produce some kind of consequences that the user does not want. For example, clicking to buy a product through points, the response time is long due to the poor network for the first time, but the user thinks that he did not click the first time, so he again Clicking is equivalent to sending a post request again, and the final result is to buy two identical products, which makes the user experience very poor;

3 Description of ideas

Ajax triggers the repeated submission of the same event continuously. One thing that can be used is that the url at the time of submission must be the same .
So just use the js variable to store the url in the encapsulated ajax method before sending the request, and after receiving the corresponding data Then, remove the variable tag. When the
misoperation leads to the second ajax request, query the existing js variable. If the variable tag exists, it means that the first response has not come back, and it is directly prohibited to send the second one. The same request.
In this way, you can avoid repeated ajax requests.


4 Package code

The following is the code that encapsulates the ajax method (at least jQuery support is required, if there is layer support, the display will be optimized and the customer experience will be better):

/**
 * 参数说明:
 * 1.url(必填)
 * 2.config(选填,各种参数的配置)
 * 		2.1.type:默认post
 * 		2.2.async:默认true
 * 		2.3.cache:默认false
 * 		2.4.dataType:默认json
 * 		2.5.contentType:默认utf8
 * 		2.6.data:默认无参数,此处一般需要使用者手动添加
 * 		2.7.packRemindType:默认:有layer插件时优先layer提示,否则为console提示.'console',控制台提示;'layer',layer提示;其他方式看需求增加,仅在函数值无效时有效
 * 3.func_suc(选填):即ajax中的success
 * 4.func_error(选填):即ajax中的error
 * 5.func_comp(选填):即ajax中的complete
 * 其他说明
 * 1.防止重复提交(自动启用,但在同步加载模式下看不出效果);
 * 2.提示模式,参考packRemindType;
 */
function ajax_pack(url,config,func_suc,func_error,func_comp){
	//1.request url repeat judge
	if(!window.lstAjaxUrl){
		window.lstAjaxUrl={};
	}
	if(window.lstAjaxUrl[url]){
		console.log('ajax (url:%s) submit repeat!',url);//重复提示在控制台
		return;
	}else{
		window.lstAjaxUrl[url]=true;
	}
	//2.init necessary param
	config=config||{};
	config.type=config.type||'post';//默认为type=get
	config.async=config.async||true;//默认为同步加载(选择此参数时,是没有必要用防重复提交功能的)
	config.cache=config.cache||false;//默认禁用缓存
	config.dataType=config.dataType||'json';
	config.contentType=config.contentType||'application/x-www-form-urlencoded; charset=utf-8';
	config.data=config.data||{};
	
	var packRemindTypeDefault=typeof(layer)==='undefined'?'console':'layer';//有layer时优先取layer
	config.packRemindType=config.packRemindType||packRemindTypeDefault;//默认:'console',控制台提示;'layer',layer提示;其他方式看需求增加,仅在函数值无效时有效
	
	var func_send;//before send,not in param
	
	if(config.packRemindType==='console'){
		func_send=function(){};
		func_suc=func_suc||function(data){console.log(data);};
		func_error=func_error||function(){console.log(url+' error');};
		func_comp=func_comp||function(){};
	}else if(config.packRemindType==='layer'){//需要layer支持
		if(!window.lstLayerLoad){
			window.lstLayerLoad={};
		}
		func_send=function(){
			window.lstLayerLoad[url]=layer.msg('加载中,请稍后...',{time:0});//layer.load(0, {shade: false,time:0}); //0代表加载的风格,支持0-2
		};
		var func_suc_init=func_suc||function(data){
			if(data.success==1){
				layer.msg(data.message,{icon:1});
			}else{
				layer.msg(data.message,{icon:2});
			}
		};
		func_suc=function(data){
			layer.close(window.lstLayerLoad[url]);
			func_suc_init(data);
		};
		var func_error_init=func_error||function(){
			layer.msg('网络错误,请稍后重试!',{icon:2});
		};
		func_error=function(){
			layer.close(window.lstLayerLoad[url]);
			func_error_init();
		};
		func_comp=func_comp||function(){};
	}else{
		console.log('nonsupport packRemindType.');
		return;
	}
	//3.get param
	$.ajax({
		url:url,
		type:config.type,
		async:config.async,
		cache:config.cache,
		dataType:config.dataType,
		contentType:config.contentType,
		data:config.data,
		beforeSend:function(){
			func_send();
		},
		success:function(data){
			if(!window.lstAjaxResult){
				window.lstAjaxResult={};
			}
			window.lstAjaxResult[url]=data;//封装结果
			func_suc(data);
		},
		error:function(){
			func_error();
		},
		complete:function(data){
			/*
			var mResult;
			if(config.dataType==='json'){
				mResult=JSON.parse(data.responseText);
			}else{
				mResult=data.responseText;
			}
			 */
			func_comp();
			window.lstAjaxUrl[url]=false;//释放url锁
		}
	});
}

Many default values ​​in the above encapsulation code are determined according to the inclination of the author's company, and users can also modify them according to their own needs (as long as this idea is ok). There is no need to replace the real url.

//某个vue methods中方法内容
var this=that;
ajax_pack(mGlobalUrl.loadOne,{
	type:'get',
	data:{
		strFormCode:strFormCode
	}
},function(data){
	that.mainData=Object.assign(that.mainData,data);
});

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324406959&siteId=291194637