嗨大家好,我是Eric。當談到API請求,我們通常會使用fetch、axios等現代的方法,但有一個我們可能忽略的功能,是由傳統的XHR(XMLHttpRequest)提供的,那就是能夠監聽請求和響應的進度。
對於 User 來說,這個功能特別有用,尤其是在上傳或下載大文件的時候,可以使用XHR來實現進度條可以顯著提升用戶體驗,接下來讓我們來了解一下XHR到底是什麼吧~
進度監聽器是一種用於監聽 HTTP 請求進度的技術。它允許開發人員實時監控請求的進度,例如文件下載或上傳時的進度,並在需要時執行相應的處理。
在 JavaScript 中,我們可以使用 XMLHttpRequest (XHR) 物件來進行網路請求,並通過添加監聽器來監控進度。
XHR 物件提供了一些與進度相關的事件,包括:
loadstart
: 請求開始時觸發。progress
: 進度更新時觸發,通常用於顯示下載或上傳進度。load
: 下載完成時觸發,表示請求成功完成並收到了完整的回應。loadend
: 下載完成後觸發,表示請求已經結束,不論成功或失敗。error
: 當請求發生錯誤時觸發,例如網絡錯誤或服務器錯誤。abort
: 當請求被取消時觸發,例如使用 xhr.abort()
方法取消請求。timeout
: 當請求超時時觸發,可以在 xhr.timeout
屬性中設置請求的超時時間。我們可以使用 xhr.addEventListener()
方法來添加進度監聽器,並在事件觸發時執行相應的處理。
javascriptCopy code
// 定義進度監聽器
function updateProgress(event) {
// 檢查是否能計算進度
if (event.lengthComputable) {
// 計算進度百分比
let progress = (event.loaded / event.total) * 100;
console.log('下載進度: ' + progress + '%');
} else {
// 當無法計算進度時,例如檔案大小未知,無法顯示進度
console.log('無法計算進度');
}
}
// 創建 XMLHttpRequest 物件並添加 Progress 監聽器
let xhr = new XMLHttpRequest();
xhr.addEventListener('loadstart', function() {
console.log('請求開始');
});
xhr.addEventListener('progress', updateProgress, false);
xhr.addEventListener('load', function() {
console.log('請求完成');
});
xhr.addEventListener('error', function() {
console.log('請求失敗');
});
xhr.addEventListener('abort', function() {
console.log('請求被取消');
});
// 發送請求
$('#uploadBtn').click(function () {
$.ajax({
url: 'http://192.168.50.154:8115/Api/DashboardDataAnalysis/CivilAircraftCount', // 請將 'your_api_endpoint' 替換為實際的 API 請求地址
type: 'POST', // 請指定請求方法
// async: true,
contentType: 'application/json',
data: JSON.stringify({
SystemParameter: 'xxx',
Token:
'xxx',
Account: 'xxx',
Name: 'xxx',
Role: '1',
}),
xhr: function () {
// 創建 XMLHttpRequest 物件並添加 Progress 監聽器
let xhr = new window.XMLHttpRequest()
// 添加 upload 屬性後不管是上傳還是下載都可以監聽
xhr.upload.addEventListener('progress', updateProgress, false) // 表示事件處理程序在事件冒泡階段被觸發(預設情況下,事件處理程序在事件捕獲階段被觸發)
xhr.addEventListener('load', transferComplete, false)
xhr.addEventListener('error', transferFailed, false)
xhr.addEventListener('abort', transferCanceled, false)
return xhr
},
success: function (response) {
console.log('成功', response)
},
error: function (error) {
console.log('失敗', error)
},
})
})
這個進度監聽器會在請求開始時觸發 loadstart
事件,並在進度更新時觸發 progress
事件,其中 updateProgress
函式會計算並顯示下載進度百分比。當請求完成時,會觸發 load
事件,如果請求失敗則會觸發 error
事件,如果請求被取消則會觸發 abort
事件。最後,在請求結束時(無論成功或失敗)都會觸發 loadend
事件。
進度監聽器通常用於顯示請求的進度,特別是在文件上傳或下載時。為了計算進度,我們需要了解以下屬性:
event.lengthComputable
: 一個布林值,表示是否能計算進度。如果為 true
,則表示能夠計算進度;如果為 false
,則表示進度無法計算,例如檔案大小未知。event.loaded
: 表示已經下載或上傳的字節數。event.total
: 表示總共需要下載或上傳的字節數。根據這些屬性,我們可以計算進度百分比,如下所示:
function updateProgress(event) {
if (event.lengthComputable) {
let progress = (event.loaded / event.total) * 100;
console.log('下載進度: ' + progress + '%');
} else {
console.log('無法計算進度');
}
}
當使用者進行文件上傳時,進度監聽器可以幫助我們實時顯示上傳進度,讓用戶了解文件上傳的狀態。
// HTML 檔案上傳表單
<input type="file" id="fileInput" />
<button onclick="uploadFile()">上傳文件</button>
// 定義事件監聽的回調函式
function updateProgress(event) {
if (event.lengthComputable) {
let progress = (event.loaded / event.total) * 100;
console.log('上傳進度: ' + progress + '%');
} else {
console.log('無法計算進度');
}
}
function transferComplete(event) {
console.log('文件上傳完成');
}
function transferFailed(event) {
console.log('文件上傳失敗');
}
function transferCanceled(event) {
console.log('文件上傳已被取消');
}
function uploadFile() {
// 獲取文件輸入元素和文件
let fileInput = document.getElementById('fileInput');
let file = fileInput.files[0];
// 使用 FormData 將文件添加到請求中
let formData = new FormData();
formData.append('file', file);
// 創建 XMLHttpRequest 物件
let xhr = new XMLHttpRequest();
// 添加進度監聽器和其他事件處理程序
xhr.upload.addEventListener('progress', updateProgress, false);
xhr.addEventListener('load', transferComplete, false);
xhr.addEventListener('error', transferFailed, false);
xhr.addEventListener('abort', transferCanceled, false);
// 請求 api
$.ajax({
code...
)}
}
// 當按鈕被點擊時,觸發上傳文件的函數
document.getElementById('uploadBtn').addEventListener('click', uploadFile);
有時候,請求可能因為網絡問題或服務器問題而長時間未響應,進而造成應用程式無法繼續運行。為了處理這種情況,我們可以添加請求超時機制。
xhr.timeout = 5000; // 設定請求超時時間(毫秒為單位)
xhr.ontimeout = function() {
console.log('請求超時');
// 可以在這裡執行相應的處理,例如顯示錯誤訊息或重試請求
};
進度監聽器不僅僅用於文件上傳或下載,它還可以應用於其他場景,例如:
參考網站推薦:
xhr:https://www.gushiciku.cn/pl/ay1L/zh-hk
fecth:https://zh.javascript.info/fetch-progress