在Web項目中,有一些請求或操做會對數據產生影響(好比新增、刪除、更新),針對這類請求通常都須要作一些保護,以防止用戶有意或無心的重複發起這樣的請求致使的數據錯亂。前端
本文總結了一些防止客戶端重複發送請求的方法。ajax
在經典場景下,瀏覽器經過Form發送請求。所以只須要在Form onsubmit時將Submit按鈕disable,就可以防止用戶雙擊致使的重複請求(這種問題通常發生在年紀大的用戶身上,他們分不清單擊和雙擊)。數據庫
可是隨着前端的發展,Form之外的請求方式也愈來愈多,好比利用各類前端框架(Vue、AngularJs、Backbone等)寫的App,他們更多的採用的是ajax的方式和後端交互。那麼前端開發人員必須在開發時針對每一個表明發起請求的UI元素作處理,像Form同樣,在發起請求的時候把相關UI元素禁用掉。json
而有些交互方式則可能連表明發起請求的UI元素都沒有,好比Segmentfault的markdown編輯器就是在一邊輸入的時候一邊保存的。那麼這時就須要前端代碼採用其餘手段來控制重複請求的發生。後端
優勢:瀏覽器
缺點:前端框架
服務端採用重定向的方式,防止用戶刷新瀏覽器發出重複請求。這是比較經典的後端控制重複請求的方式,由於一旦重定向成功後,用戶刷新瀏覽器所刷新的是那個重定向地址,而不是數據操做地址。服務器
優勢:markdown
缺點:cookie
結合方法一和方法二的話卻是能夠解決大部分問題,可是解決不了如下問題:
token的流程是這樣的:
關鍵點在於:
那麼token是以怎樣的形式傳輸的呢?我認爲有如下兩種方式:
Cookie:
推薦使用這種方式,由於瀏覽器每次都會將cookie攜帶在請求裏一併發出,因此前端發送請求的代碼都不須要修改,只要在發送請求前問服務器拿token就好了。
好比在進入Form頁面時,服務器將token以cookie的形式一併攜帶在響應中,那麼前端Form提交時,就會將cookie一併攜帶在請求中,前端的代碼一點都不須要修改。
json:
前端發起ajax請求像後端拿token,後端以json的形式返回token,前端發送請求時將token攜帶在請求中,後端檢驗。
這種方式比Cookie稍微麻煩的地方是,前端必須寫一些代碼來保存這個token,而後在發送請求的地方要寫一些代碼把token攜帶在請求裏。
優勢:
缺點:
若是請求會insert數據,而這個數據正好存在業務主鍵,那麼能夠利用數據庫的惟一約束來作進一步的防護。
有些業務情形下,請求是冪等的,這就意味着能夠不用爲重複發生請求而煩惱了——至少在業務邏輯層面不用煩惱了。