此次測試是因爲網絡請求原因,post提交數據後,後臺反應比前臺慢,所以爲了拿到請求數據,post會自動多次請求。我這裏是監聽視頻播放,給用戶追加積分。
防止數據重複提交原理:每一輪數據提交的時候,前端建立一個時間戳作爲判斷數據是否重複的基準。後端執行時,將此次基準時間戳進行session存儲,在此次程序執行完畢後,前端拿到返回數據,等待幾秒鐘再修改下一輪基準時間戳。這裏要注意,當我們第二輪時間戳進入後臺時,要將前一輪的時間戳刪除,存儲新的,判斷是否爲新時間戳很簡單,將前一輪的時間戳與新一輪作比較,相等即爲舊(爲舊說明是重複提交的,直接return 返回,不繼續執行),不等即爲新。
後臺框架thinkphp6:
//追加積分
public function addIntegral(){
$info = input();
//用戶id
$uid = $this->uid;
$integral = $info['sy_integral'];
//系統追加積分
//獲取當前數據提交的時間,以時間戳作爲數據是否提交的基準,當數據提交進來的時候,存儲當前數據提交時間,執行後續操作,前端在數據返回後稍微等待幾秒鐘再做第二輪數據提交時間的修改。
if(empty(session::get('isSubmit'))){
session::set('isSubmit',$info['timestamp']);
}else{
//判斷當前數據提交時間是否等於上一次提交,如果相等說明是後端還未返回數據前端重複提交的,此時直接返回,停止重複請求,如果兩次數據提交時間不相等,說明這是一輪新的數據提交,此時需要刪除記錄的上一輪數據提交時間,重新存儲此次的數據提交時間,以此類推……
if(session::get('isSubmit') == $info['timestamp']){
return false;
//return json(['info'=>'積分追加錯誤,數據重複','status'=>0]);
}else{
//刪除session
session::delete('isSubmit');
session::set('isSubmit',$info['timestamp']);
}
}
$res = Db::name('users')->where('us_id',$uid)->inc('us_integral')->update();
if($res){
integralAdd($uid,'觀看微課堂視頻+'.$integral,1,$integral);
return json(['info'=>'你觀看了10分鐘視頻,獎勵您'.$integral.'個積分','status'=>1]);
}else{
return json(['info'=>'積分追加錯誤','status'=>0]);
}
}
前端js代碼:
//監聽播放時間變化,追加積分
var sy_integral = Number("{$sy_integral}"); //每次觀看視頻追加的積分
var date = new Date();
var timestamp = date.valueOf(); //時間戳
$("#input").val(timestamp); //隱藏時間戳,這個input輸入框可自行在頁面輸入,使用隱藏域
$("video").on("timeupdate",function(even){ //監聽視頻播放時間
var num = Math.floor(this.currentTime); //視頻播放時間
var time = $("#input").val(); //獲取此次數據提交的時間
if(num > 0 && num % 60 == 0){
$.post("{:url('Video/addIntegral')}",{'sy_integral':sy_integral,'timestamp':time},function(res){
if(res.status == 1){
mui.toast(res.info,{ duration: 1500, type:'div' });
//3S後執行,稍微等待幾秒鐘後再修改下一輪數據提交的基準時間
setTimeout(function(){
$("#input").val((new Date()).valueOf()); //時間戳
},3000);
return true;
}else{
//mui.toast(res.info,{ duration: 1500, type:'div' });
return false;
}
},'json');
}
// 總時長
//$("#duration").val(Math.floor(this.duration));
});