一道面試題 如何防止非同步請求的重複提交

2022-05-08 23:45:20 字數 2662 閱讀 9447

11月14日更新:

首先謝謝大家對這個問題的討論,為了後來的童鞋方便瀏覽,我結合大家的**,重新補充編輯此貼,為標藍色加粗字型部分。

今天面試時考官問了一道題,以下是大致的回憶:

問題大意: 如果點選乙個按鈕傳送非同步請求,如何防止短時間內使用者重複提交,從而造成資料覆蓋等問題:

我回答的解決方法有:

1. 提交後disable掉按鈕,再次點選文字框時enable按鈕

(11月14號更新:

提交後disable按鈕是常用方法,

外觀表現上有:1. disable 按鈕,在按鈕上顯示提交中等資訊

2. 設定遮罩層,遮罩層上顯示提交資訊。

在**處理邏輯上是:

第一步: 設定開關變數。

第二步: 提交前關掉按鈕

第三步: 在**函式中開啟按鈕

var isquery = false

;function

query() ,

success:

function

() ,

error:

function

() })

} else

}

以下一段文字僅是補充當時的場景,disable 按鈕的方式看上面**即可,以下可忽略  : )

上文中 」再次點選文字框時enable 按鈕使「 不是disable 方法的一部分,只是為了補充 用開關變數disable按鈕的思路可能存在乙個問題:如果伺服器端處理時間很長,甚至是伺服器端掛掉了,一直在等超時的期間客戶沒法再次輸入,因此設定了 再次點選文字框時enable 按鈕 )

面試官追問,那麼如果使用者還是快速地點選文字框,還是能快速地提交,

2. 我想到了設定乙個緩衝時間,例如200ms,200ms內的重複請求忽略,只執行最後一次的請求。

這個方法的**:

var timer = null

;btn.addeventlistener('click', function

() timer = settimeout(function

() , 200);

}, false);

我說這會影響到所有的使用者的每次請求都有延遲,然後繼續想:

3. 所以想到提交後disable,然後settimeinterval,每隔一定時間,例如一秒鐘,如果是disable的話那麼enable 

( 其實這是在嘗試解決上面提到的如果伺服器端處理時間特別長,使用者想重新輸入的問題。

ps: 因為是面試,我這裡是為複述整個故事,其他童鞋可以忽略這段 )

面試官指出,那麼這個計時器就一直需要在執行咯,是啊,這樣也是在消耗, (正在寫部落格的時候我在想能否設定乙個計數器,如果連續好幾次都是disable狀態的話,可以移除定時器)

於是繼續想:

4. 我想對每個非同步請求判斷下ip,如果是短時間內快速的重複提交,設定乙個閾值,超過則判斷為spam,把ip位址ban掉或者忽略請求,但這個缺陷是對每乙個請求都進行了額外操作。

然後面試官說這要後端配合,如果是前端呢?

5. 我想到了設定hash值,發非同步請求時帶上乙個hash值,如果伺服器端在處理上乙個請求還沒有完成時又來了新請求,那麼可以丟棄,繼續等待返回,這樣不會覆蓋資料。

然後發現,有走到需要後端配合了,面試官繼續問,如果不要後端配合,如果僅僅是前端怎麼做,

6. 我只好想到傳送非同步請求時候帶上時間戳/hash值,返回資料的時候也帶上時間戳/hash值,然後看是不是最近傳送的那個請求,是則渲染,否則丟棄。

但是面試官在問有沒有更好的方法,

我當時如實告訴面試官想不出來了,很抱歉,

剛才我看了下 xhr 物件的 api,發現有 abort() 方法,能立即取消請求,這個當然方便,每次保留上一次提交的xhr物件引用,下次點選時先abort() 上乙個xhr請求,再重新傳送請求,但是當時不知道這個方法,其實自己有想到是不是 xhr物件直接有取消請求的方法,但轉而一想面試不可能這麼簡單吧,然後我不確定這個方法是否存在。所以沒回答這個方法。

(abort()  方法取消當前響應,關閉連線並且結束任何未決的網路活動。

這個方法把 xmlhttprequest 物件重置為 readystate 為 0 的狀態,並且取消所有未決的網路活動。例如,如果請求用了太長時間,而且響應不再必要的時候,可以呼叫這個方法。請見:

)

11月20日更新:感謝面試官,雖然面試掛了,還能有機會再次溝通,得知 abort()方法其實是當時面試官心裡期待的回答,那個滾動條優化,面試官期待的是 throttle函式,再次感謝。

當然不知道面試官希望我能回答出來的更好方法是什麼,所以請有看到的朋友能不吝賜教,謝謝。

一道面試題

一道面試題 射擊運動員10發打中90環有多少種可能,請編寫程式計算出來,並列印出結果,0環和10環均有效。打中90環就是沒打中10環,所以打中90環跟打中10環的可能性是一樣的。然後開始遞迴狂打槍,一到10就記錄 if params i 10 在迴圈的控制中已經排除了大於10的可能性 i 10 pa...

一道面試題

前些時候在找工作,就在準備結束此次找工作歷程的時候,去了一家公司面試,去了之後技術經理直接帶到一台電腦旁,給了一張紙條,上面是這樣的題目 用c或c 來實現 1 建立一棵樹,該樹的深度是隨機的,每個節點的位元組點數是隨機的。2 給每個節點分配一段隨機大小的記憶體空間,給每個節點賦乙個隨機數。3 遍歷這...

一道面試題

如果n為偶數,則將它除以2,如果n為奇數,則將它加1或者減1。問對於乙個給定的n,怎樣才能用最少的步驟將它變到1。例如 n 61 n 60 n 2 30 n 2 15 n 16 n 2 8 n 2 4 n 2 2 n 2 1 public class myclass public static vo...