JavaScript實現(xiàn)獲取網(wǎng)絡(luò)通信進(jìn)度
網(wǎng)絡(luò)請求是現(xiàn)代Web開發(fā)中不可或缺的一部分,無論是從服務(wù)器獲取資源,還是提交數(shù)據(jù),了解請求的進(jìn)度對于提升用戶體驗非常關(guān)鍵。本文將詳細(xì)介紹如何使用Fetch API和XMLHttpRequest(XHR)來執(zhí)行網(wǎng)絡(luò)請求,并重點說明如何獲取這兩種方法的網(wǎng)絡(luò)請求進(jìn)度。此外也將探討在使用XHR進(jìn)行文件上傳時如何獲取上傳進(jìn)度,以及Fetch API的局限性。
Fetch基礎(chǔ)
Fetch API提供了一個強大且靈活的接口,用于對網(wǎng)絡(luò)請求進(jìn)行操作。它是一個低級別的API,可以控制請求的各個方面。以下為一個基礎(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)用返回了一個Promise
,當(dāng)響應(yīng)到達(dá)且成功時,則進(jìn)入.then
方法處理,如果有錯誤則在.catch
中處理。
獲取Fetch請求進(jìn)度
由于Fetch返回的Response
對象并不直接暴露原始數(shù)據(jù)流的讀取進(jìn)度。但是,Response
對象的body
屬性是一個ReadableStream
,可以用來讀取數(shù)據(jù)流。
要獲得Fetch請求的進(jìn)度,可以通過讀取數(shù)據(jù)流中的chunk大小來估計進(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));
在這個示例中,ReadableStream
被用來處理原始數(shù)據(jù)流。response.body.getReader().read()
返回了數(shù)據(jù)塊,隨著數(shù)據(jù)塊的接收,可以計算已經(jīng)接收的總數(shù)據(jù)量receivedLength
以及估算進(jìn)度。
XMLHttpRequest基礎(chǔ)
XMLHttpRequest是一個老牌技術(shù),但仍被廣泛用于瀏覽器中執(zhí)行網(wǎng)絡(luò)請求。
以下是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)建了一個新的XMLHttpRequest
對象,然后通過.open()
方法初始化了一個請求。在.onload
處理函數(shù)中處理響應(yīng),并在.onerror
中處理可能發(fā)生的錯誤。
獲取XHR請求進(jìn)度
與Fetch API不同,XHR提供了progress
事件,可用于追蹤請求的進(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在上傳文件時可以追蹤上傳進(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)建一個表單數(shù)據(jù)對象。xhr.upload
對象允許綁定progress
事件,從而追蹤上傳進(jìn)度。
為什么Fetch無法獲取上傳進(jìn)度
Fetch API目前在規(guī)范中并不支持上傳進(jìn)度的監(jiān)控。fetch()
函數(shù)返回的Promise直到請求完成后才會解決,且不提供中間狀態(tài)的信息。由于Fetch API的設(shè)計偏向提供一套流式的數(shù)據(jù)處理方式,而對請求中的狀態(tài)管理并不直接提供支持。
開發(fā)者可以使用Service Worker技術(shù)或可觀察對象(Observables)作為替代方案來一定程度上監(jiān)控上傳進(jìn)度,但這些方法實現(xiàn)起來相對復(fù)雜,沒有XHR在這方面的原生優(yōu)勢。
總結(jié)
理解并實現(xiàn)網(wǎng)絡(luò)請求進(jìn)度的監(jiān)控,對于創(chuàng)建友好的用戶體驗至關(guān)重要。通過使用XMLHttpRequest
的progress
事件或利用Fetch API的ReadableStream
接口,開發(fā)者可以為用戶提供實時反饋,增強其對應(yīng)用的信心和滿意度。此外,在文件上傳場景下,由于Fetch API存在一定的限制,XHR提供了一個更為適合的選擇,以準(zhǔn)確獲取上傳進(jìn)度。盡管這些技術(shù)各有優(yōu)劣,但選擇合適的方法對網(wǎng)絡(luò)請求進(jìn)度的監(jiān)控可以顯著改善網(wǎng)頁應(yīng)用的互動性。在未來,隨著Web標(biāo)準(zhǔn)的發(fā)展,F(xiàn)etch API有可能增加更完善的監(jiān)控傳輸進(jìn)度的功能,但截止目前,XHR仍是追蹤進(jìn)度的首選工具。
到此這篇關(guān)于JavaScript實現(xiàn)獲取網(wǎng)絡(luò)通信進(jìn)度的文章就介紹到這了,更多相關(guān)JavaScript獲取網(wǎng)絡(luò)通信進(jìn)度內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用JS組件實現(xiàn)帶ToolTip驗證框的實例代碼
這篇文章主要介紹了使用JS組件實現(xiàn)帶ToolTip驗證框的實例代碼,需要的朋友可以參考下2017-08-08webpack?output.library的16?種取值方法示例
這篇文章主要為大家介紹了webpack?output.library的16?種取值方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Javascript實現(xiàn)帶關(guān)閉按鈕的網(wǎng)頁漂浮廣告代碼
帶有關(guān)閉功能的漂浮圖片的實現(xiàn)方法有很多,下面為大家介紹下使用Javascript是如何實現(xiàn)的,喜歡的額朋友可以了解下2014-01-01使用Bootstrap typeahead插件實現(xiàn)搜索框自動補全的方法
這篇文章主要介紹了使用Bootstrap typeahead插件實現(xiàn)搜索框自動補全的方法的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-07-07javascript之Partial Application學(xué)習(xí)
在數(shù)學(xué)中,一個函數(shù)是描述每個輸入值對應(yīng)唯一輸出值的這種對應(yīng)關(guān)系,符號為 f(x)。例如,表達(dá)式 f(x)=x2表示了一個函數(shù) f,其中每個輸入值x都與唯一輸出值x2相聯(lián)系2013-01-01