重復請求問題
使用Promise和AbortController來實現思路是:通過在會話緩存中存儲和比較請求信息,來防止用戶在短時間內重復提交相同的請求。
具體思路如下:
- 存儲請求信息:每次請求時,將請求的相關信息(如URL、數據和時間)存儲在會話緩存中,以便后續比較。
- 檢查緩存:在處理新的請求時,首先從會話緩存中獲取上一次請求的信息。
- 判斷條件:通過比較當前請求和上一次請求的信息,判斷是否為重復提交。具體判斷條件包括:
- 請求的URL是否相同。
- 請求的數據是否相同。
- 當前請求時間與上次請求時間的差是否小于設定的間隔時間(例如1秒)。
- 處理重復提交:如果滿足重復提交的條件,則阻止當前請求的處理,并返回一個錯誤信息,提示用戶“數據正在處理,請勿重復提交”。
- 更新緩存:如果不滿足重復提交的條件,則將當前請求的信息更新到會話緩存中,以便下次請求時進行比較。
// 假設我們有一個請求函數
function sendRequest(requestObj) {// 創建一個新的AbortController實例const controller = new AbortController();const signal = controller.signal;// 檢查會話緩存中的請求信息const sessionObj = cache.session.getJSON('sessionObj');const interval = 1000; // 間隔時間(ms)if (sessionObj) {const s_url = sessionObj.url;const s_data = sessionObj.data;const s_time = sessionObj.time;// 檢測重復請求if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {const message = '數據正在處理,請勿重復提交';console.warn(`[${s_url}]: ` + message);// 取消當前請求controller.abort();return Promise.reject(new Error(message));}}// 更新會話緩存cache.session.setJSON('sessionObj', requestObj);// 發起請求return fetch(requestObj.url, { method: 'POST', body: JSON.stringify(requestObj.data), signal }).then(response => {if (!response.ok) {throw new Error('請求失敗');}return response.json();}).catch(error => {if (error.name === 'AbortError') {console.log('請求已取消');} else {console.error('請求錯誤:', error);}throw error;});
}// 使用如下。
const requestObj = {url: 'https://example.com/api',data: { key: 'value' },time: Date.now()
};sendRequest(requestObj).then(data => {console.log('請求成功:', data);}).catch(error => {console.error('請求失敗:', error.message);});