Web項目如何防止客戶端重複發送請求

在Web項目中,有一些請求或操做會對數據產生影響(好比新增、刪除、更新),針對這類請求通常都須要作一些保護,以防止用戶有意或無心的重複發起這樣的請求致使的數據錯亂。前端

本文總結了一些防止客戶端重複發送請求的方法。ajax

方法一:JS監聽Form的onsubmit事件

在經典場景下,瀏覽器經過Form發送請求。所以只須要在Form onsubmit時將Submit按鈕disable,就可以防止用戶雙擊致使的重複請求(這種問題通常發生在年紀大的用戶身上,他們分不清單擊和雙擊)。數據庫

可是隨着前端的發展,Form之外的請求方式也愈來愈多,好比利用各類前端框架(Vue、AngularJs、Backbone等)寫的App,他們更多的採用的是ajax的方式和後端交互。那麼前端開發人員必須在開發時針對每一個表明發起請求的UI元素作處理,像Form同樣,在發起請求的時候把相關UI元素禁用掉。json

而有些交互方式則可能連表明發起請求的UI元素都沒有,好比Segmentfault的markdown編輯器就是在一邊輸入的時候一邊保存的。那麼這時就須要前端代碼採用其餘手段來控制重複請求的發生。後端

優勢:瀏覽器

  1. 不須要後端寫代碼

缺點:前端框架

  1. 不存在統一的解決方案,必須針對每種狀況寫處理代碼
  2. 沒法控制瀏覽器刷新發起的重複請求
  3. 前端開發人員忘記寫相關代碼
  4. 沒法控制惡意的重複請求,好比繞過瀏覽器直接發起

方法二:Http Status Code 302(後端重定向)

服務端採用重定向的方式,防止用戶刷新瀏覽器發出重複請求。這是比較經典的後端控制重複請求的方式,由於一旦重定向成功後,用戶刷新瀏覽器所刷新的是那個重定向地址,而不是數據操做地址。服務器

優勢:markdown

  1. 不須要寫前端代碼

缺點:cookie

  1. 在還未響應302以前,所發起的重複請求,好比:用戶快速的雙擊、刷新瀏覽器
  2. 在某些前端程序裏(好比SPA),不能使用重定向
  3. 後端開發人員忘記寫相關代碼
  4. 沒法控制惡意的重複請求,好比繞過瀏覽器直接發起

方法三:結合方法一和方法二

結合方法一和方法二的話卻是能夠解決大部分問題,可是解決不了如下問題:

  1. 在還未響應302以前,用戶刷新瀏覽器致使的重複請求
  2. 有些場景下壓根不能使用重定向
  3. 前、後端開發人員忘記寫相關代碼
  4. 沒法控制惡意的重複請求,好比繞過瀏覽器直接發起

方法四:token方式

token的流程是這樣的:

  1. 在瀏覽器發送請求前,先到服務端索要token
  2. 瀏覽器發送請求時,將token一併提交
  3. 服務端檢查請求是否攜帶token、token是否有效(好比是否正確、是否過時)。若是不正確則響應失敗;若是正確則銷燬token,繼續業務邏輯。

關鍵點在於:

  1. 每一個token都是一次性且有過時時間的,可以防止token前端代碼bug形成的重複利用和無限利用。
  2. 服務器要求請求必須攜帶token,可以避免前端開發人員漏寫相關代碼。

那麼token是以怎樣的形式傳輸的呢?我認爲有如下兩種方式:

Cookie

推薦使用這種方式,由於瀏覽器每次都會將cookie攜帶在請求裏一併發出,因此前端發送請求的代碼都不須要修改,只要在發送請求前問服務器拿token就好了。

好比在進入Form頁面時,服務器將token以cookie的形式一併攜帶在響應中,那麼前端Form提交時,就會將cookie一併攜帶在請求中,前端的代碼一點都不須要修改。

json

前端發起ajax請求像後端拿token,後端以json的形式返回token,前端發送請求時將token攜帶在請求中,後端檢驗。

這種方式比Cookie稍微麻煩的地方是,前端必須寫一些代碼來保存這個token,而後在發送請求的地方要寫一些代碼把token攜帶在請求裏。

優勢

  1. 前端代碼能夠寫的少一些,好比禁用UI元素的代碼能夠不寫
  2. 可以解決在還未響應302以前,用戶刷新瀏覽器致使的重複請求
  3. 適應有些場景下壓根不能使用重定向

缺點

  1. 前、後端開發人員忘記寫相關代碼。這個真的解決不了。
  2. 沒法控制經過腳本運行的,具備整套流程的惡意請求。這種請求在程序看來徹底合法,但卻屬於惡意行爲,針對這類惡意行爲的防控屬於另外一個話題,本人不懂,因此在這裏就很少講了。

方法五:利用數據庫的惟一約束

若是請求會insert數據,而這個數據正好存在業務主鍵,那麼能夠利用數據庫的惟一約束來作進一步的防護。

方法六:請求冪等化

有些業務情形下,請求是冪等的,這就意味着能夠不用爲重複發生請求而煩惱了——至少在業務邏輯層面不用煩惱了。

相關文章
相關標籤/搜索