JavaScript實(shí)現(xiàn)獲取網(wǎng)絡(luò)通信進(jìn)度
網(wǎng)絡(luò)請(qǐng)求是現(xiàn)代Web開發(fā)中不可或缺的一部分,無論是從服務(wù)器獲取資源,還是提交數(shù)據(jù),了解請(qǐng)求的進(jìn)度對(duì)于提升用戶體驗(yàn)非常關(guān)鍵。本文將詳細(xì)介紹如何使用Fetch API和XMLHttpRequest(XHR)來執(zhí)行網(wǎng)絡(luò)請(qǐng)求,并重點(diǎn)說明如何獲取這兩種方法的網(wǎng)絡(luò)請(qǐng)求進(jìn)度。此外也將探討在使用XHR進(jìn)行文件上傳時(shí)如何獲取上傳進(jìn)度,以及Fetch API的局限性。
Fetch基礎(chǔ)
Fetch API提供了一個(gè)強(qiáng)大且靈活的接口,用于對(duì)網(wǎng)絡(luò)請(qǐng)求進(jìn)行操作。它是一個(gè)低級(jí)別的API,可以控制請(qǐng)求的各個(gè)方面。以下為一個(gè)基礎(chǔ)的Fetch API調(diào)用示例,它通過網(wǎng)絡(luò)獲取資源。
fetch('https://example.com/data')
.then(response => {
if(response.ok) {
return response.json(); // Assuming the response is JSON
}
throw new Error('Network response was not ok.');
})
.then(data => console.log(data))
.catch(error => console.error('Fetch error:', error));
在上述代碼中,fetch函數(shù)調(diào)用返回了一個(gè)Promise,當(dāng)響應(yīng)到達(dá)且成功時(shí),則進(jìn)入.then方法處理,如果有錯(cuò)誤則在.catch中處理。
獲取Fetch請(qǐng)求進(jìn)度
由于Fetch返回的Response對(duì)象并不直接暴露原始數(shù)據(jù)流的讀取進(jìn)度。但是,Response對(duì)象的body屬性是一個(gè)ReadableStream,可以用來讀取數(shù)據(jù)流。
要獲得Fetch請(qǐng)求的進(jìn)度,可以通過讀取數(shù)據(jù)流中的chunk大小來估計(jì)進(jìn)度。
fetch('https://example.com/data')
.then(response => {
const contentLength = response.headers.get('Content-Length');
let receivedLength = 0; // received that many bytes at the moment
let reader = response.body.getReader();
let chunks = []; // array of received binary chunks (comprises the body)
return new ReadableStream({
start(controller) {
function push() {
// "done" is a Boolean and value a "Uint8Array"
reader.read().then(({done, value}) => {
if (done) {
controller.close();
return;
}
chunks.push(value);
receivedLength += value.length;
console.log(`Received ${receivedLength} of ${contentLength}`);
// Enqueue the next data chunk into our target stream
controller.enqueue(value);
push();
});
}
push();
}
});
})
.then(stream => new Response(stream))
.then(response => response.blob())
.then(blob => console.log(blob)) // Do whatever with the blob
.catch(error => console.error('Fetch error:', error));
在這個(gè)示例中,ReadableStream被用來處理原始數(shù)據(jù)流。response.body.getReader().read()返回了數(shù)據(jù)塊,隨著數(shù)據(jù)塊的接收,可以計(jì)算已經(jīng)接收的總數(shù)據(jù)量receivedLength以及估算進(jìn)度。
XMLHttpRequest基礎(chǔ)
XMLHttpRequest是一個(gè)老牌技術(shù),但仍被廣泛用于瀏覽器中執(zhí)行網(wǎng)絡(luò)請(qǐng)求。
以下是XHR的基本用法:
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/data', true);
xhr.onload = function() {
if (xhr.status === 200) {
let data = JSON.parse(xhr.responseText);
console.log(data);
} else {
console.error('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send();
在上述代碼段中,首先創(chuàng)建了一個(gè)新的XMLHttpRequest對(duì)象,然后通過.open()方法初始化了一個(gè)請(qǐng)求。在.onload處理函數(shù)中處理響應(yīng),并在.onerror中處理可能發(fā)生的錯(cuò)誤。
獲取XHR請(qǐng)求進(jìn)度
與Fetch API不同,XHR提供了progress事件,可用于追蹤請(qǐng)求的進(jìn)度。
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/data', true);
xhr.onprogress = function(event) {
if (event.lengthComputable) {
let percentComplete = (event.loaded / event.total) * 100;
console.log(`Progress: ${percentComplete}%`);
}
};
xhr.onload = function() {
// The request is complete and data is available in `xhr.responseText`
};
xhr.onerror = function() {
console.error('Request failed');
};
xhr.send();
在上面的代碼中,.onprogress事件處理器可以獲取當(dāng)前進(jìn)度。event.loaded是已下載的字節(jié)數(shù),而event.total是總字節(jié)數(shù)(如果lengthComputable為true)。
使用XHR進(jìn)行文件上傳并獲取進(jìn)度
XHR在上傳文件時(shí)可以追蹤上傳進(jìn)度。以下是xhr上傳文件并獲取進(jìn)度的示例:
let file = document.getElementById('fileupload').files[0]; // Assuming <input type="file" id="fileupload">
let xhr = new XMLHttpRequest();
let formData = new FormData();
formData.append('file', file);
xhr.upload.onprogress = function(event) {
if (event.lengthComputable) {
let percentComplete = (event.loaded / event.total) * 100;
console.log(`Upload Progress: ${percentComplete}%`);
}
};
xhr.onload = function() {
if (xhr.status === 200) {
console.log('File successfully uploaded');
} else {
console.error('Upload failed. Returned status of ' + xhr.status);
}
};
xhr.onerror = function() {
console.error('Upload failed.');
};
xhr.open('POST', 'https://example.com/upload', true);
xhr.send(formData);
上述示例中,FormData用于構(gòu)建一個(gè)表單數(shù)據(jù)對(duì)象。xhr.upload對(duì)象允許綁定progress事件,從而追蹤上傳進(jìn)度。
為什么Fetch無法獲取上傳進(jìn)度
Fetch API目前在規(guī)范中并不支持上傳進(jìn)度的監(jiān)控。fetch()函數(shù)返回的Promise直到請(qǐng)求完成后才會(huì)解決,且不提供中間狀態(tài)的信息。由于Fetch API的設(shè)計(jì)偏向提供一套流式的數(shù)據(jù)處理方式,而對(duì)請(qǐng)求中的狀態(tài)管理并不直接提供支持。
開發(fā)者可以使用Service Worker技術(shù)或可觀察對(duì)象(Observables)作為替代方案來一定程度上監(jiān)控上傳進(jìn)度,但這些方法實(shí)現(xiàn)起來相對(duì)復(fù)雜,沒有XHR在這方面的原生優(yōu)勢(shì)。
總結(jié)
理解并實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求進(jìn)度的監(jiān)控,對(duì)于創(chuàng)建友好的用戶體驗(yàn)至關(guān)重要。通過使用XMLHttpRequest的progress事件或利用Fetch API的ReadableStream接口,開發(fā)者可以為用戶提供實(shí)時(shí)反饋,增強(qiáng)其對(duì)應(yīng)用的信心和滿意度。此外,在文件上傳場(chǎng)景下,由于Fetch API存在一定的限制,XHR提供了一個(gè)更為適合的選擇,以準(zhǔn)確獲取上傳進(jìn)度。盡管這些技術(shù)各有優(yōu)劣,但選擇合適的方法對(duì)網(wǎng)絡(luò)請(qǐng)求進(jìn)度的監(jiān)控可以顯著改善網(wǎng)頁應(yīng)用的互動(dòng)性。在未來,隨著Web標(biāo)準(zhǔn)的發(fā)展,F(xiàn)etch API有可能增加更完善的監(jiān)控傳輸進(jìn)度的功能,但截止目前,XHR仍是追蹤進(jìn)度的首選工具。
到此這篇關(guān)于JavaScript實(shí)現(xiàn)獲取網(wǎng)絡(luò)通信進(jìn)度的文章就介紹到這了,更多相關(guān)JavaScript獲取網(wǎng)絡(luò)通信進(jìn)度內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript正則表達(dá)式.test()基礎(chǔ)講解與實(shí)際應(yīng)用案例
正則表達(dá)式是JavaScript中處理字符串的強(qiáng)大工具,而test()方法則是其中最常用的方法之一,這篇文章主要介紹了JavaScript正則表達(dá)式.test()基礎(chǔ)講解與實(shí)際應(yīng)用案例的相關(guān)資料,需要的朋友可以參考下2026-05-05
Javascript 寫的簡(jiǎn)單進(jìn)度條控件
2008-01-01
uniapp實(shí)現(xiàn)tabs切換(可滑動(dòng))效果實(shí)例
這篇文章主要給大家介紹了關(guān)于uniapp實(shí)現(xiàn)tabs切換(可滑動(dòng))效果的相關(guān)資料,tabs切換無論是在app端還是小程序或者H5頁面都是很常見的功能,文中通過實(shí)例代碼介紹的很詳細(xì),需要的朋友可以參考下2023-07-07
使用JavaScript?+?HTML5?Canvas實(shí)現(xiàn)互動(dòng)愛心雨完整代碼
canvas是HTML5中推出的新功能,可以在頁面上生成一個(gè)畫布,使用js可以在畫布上繪制一些圖形,這篇文章主要介紹了使用JavaScript?+?HTML5?Canvas實(shí)現(xiàn)互動(dòng)愛心雨的相關(guān)資料,需要的朋友可以參考下2025-03-03
JavaScript實(shí)現(xiàn)生成動(dòng)態(tài)表格和動(dòng)態(tài)效果的方法詳解
這篇文章主要介紹了如何通過JavaScript語言實(shí)現(xiàn)動(dòng)圖表格的生成以及動(dòng)態(tài)效果的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的可以了解一下2022-02-02

