在Uliweb中防止表單屢次提交的實現

防止表單重複提交併非一個新問題,在這篇文章《Prevent Duplicate Form Submission》就講了許多的辦法:前端

  1. 禁止提交按鈕
  2. Post/Redirect/Get 模式
  3. 保存惟一Token值到session中
  4. 在數據庫中増加一致性檢查

以上幾種模式能夠根據須要來實現。下面我分別介紹一下對於1.3的實踐。jquery

禁止提交按鈕

對於1.我使用jquery,所以能夠在執行$.ajax時響應beforeSend和compele回調,如:web

complete: function(){
    $('#addForm').find(":submit").prop('disabled', false)
},
beforeSend:function(){
    $('#addForm').find(":submit").prop('disabled', true)
}

還能夠考慮在form的submit時禁止掉提交鈕,可是返回時經過complete來恢復:ajax

$('#addForm').submit(function(e){
    $(this).find(':submit').prop('disabled', true);
});

保存惟一Token值到session中

在uliweb中,我將generic的AddView和EditView添加了防止重複提交的保護。爲何沒有直接在Form上添加,是由於我要使用到cache,而這個和應用相關,而Form自己和應用無所,因此沒在Form上添加。還有一個緣由是Form自己不實現操做流程,因此不區分顯示和提交,所以也不方便。而在AddView和EditView中實現了GET和POST的不一樣處理,因此能夠方便添加相應的檢查。如今是在AddView和EditView中添加了protect參數,缺省爲True。這樣缺省狀況下,防止屢次提交是直接生效的。在uliweb的實現中沒有使用session,而是cache。由於uliweb的session不是立刻修改以後就保存到存儲中,而是在返回時才保存。所以沒法有效控制併發。數據庫

基本的實現流程是:session

  1. 用戶請求Form,後臺判斷出是GET方法,則建立一個token,而後保存到cache中,值爲1,同時向form中添加一個隱藏字段,用來在前端保存這個token。
  2. 用戶提交數據,後臺從提交的數據中取出token值,而後使用這個值做爲key將cache中的值減1,若是,返回值是0,表示第一次提交,繼續處理;若是小於0,表示屢次提交,返回錯誤。
  3. 若是第一次提交,form校驗若是成功,則返回前端。若是出錯,則重置token的值爲1,用於出錯後的提交。
  4. cache中的值將會在1小時以後被回收。這塊暫時沒有處理爲可配置的。

從以上流程能夠看出,先後臺要分別保存相同的token,所以若是get時沒有經過AddView或EditView的處理或form不是處理後的form,都將形成token信息不一致。所以要自已去想辦法處理。併發

相關文章
相關標籤/搜索