問題描述:
就是前端發起請求後,後端還未全部返回請求數據時,終止請求,不再返回數據。
問題案例:
【附件上傳】:前端上傳一個1G大小的壓縮文件時,耗時大概一兩分鐘,在上傳到50%的時候,用戶要取消上傳,此時,就要執行如題所探討的終止請求動作。
解決思路:
由於目前前後端交互使用的技術有fetch/ajax/axios,那麼基本思路就是基於各自提供的接口,實現請求終止動作。
【fetch】終止前端發起的請求
解決方案:使用AbortController 構造器,代碼圖如下:
var controller = new AbortController();
var signal = controller.signal;
var downloadBtn = document.querySelector('.download');
var abortBtn = document.querySelector('.abort');
downloadBtn.addEventListener('click', fetchVideo);
abortBtn.addEventListener('click', function() {
controller.abort();
console.log('Download aborted');
});
function fetchVideo() {
...
fetch(url, {signal}).then(function(response) {
...
}).catch(function(e) {
reports.textContent = 'Download error: ' + e.message;
})
}
使用說明:a.該構造器對360瀏覽器不兼容,使用要考慮瀏覽器(待普及)
【 axios】終止前端發起的請求
解決方案:利用axios請求的config參數,向axios添加一個包含cancelToken的config配置對象。
方法一代碼如下:
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// handle error
}
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');
方法二代碼如下:
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// An executor function receives a cancel function as a parameter
cancel = c;
})
});
// cancel the request
cancel();
使用說明:a.方法一可能會終止所有的axios請求(也就是說,使用
source.cancel('Operation canceled by the user.');
後,後續的所有axios都會被終止(須自行驗證))
b.使用方法二,多個用到終止請求的請求方法,可以公用一個相對全局的cancel變量,在每個請求方法有cancel=c,可以實現重置cancel。