JavaScript獲取上傳進度的幾種方式實現
獲取上傳進度的幾種方式
今天測試說咱們的上傳后的等待界面都沒有l(wèi)oading, 看起來不像是等待界面需要優(yōu)化。然后產品說參考下其他業(yè)務的上傳搞下吧。 我以為就一個loading的事,發(fā)現其他業(yè)務上傳使用的是環(huán)形、線形進度條。我說現在接口是沒有返回當前進度的,如果是以上傳完成后的文件數量(因為我們是一個個文件上傳分批次調的接口)做判斷也不太準確,因為文件有大有小的。
后面就找另外一個前端同事聊了下他告訴我說axios是有監(jiān)聽整個上傳進度api的,那我就針對文件上傳去了解了下做以下總結:
前端使用axios實現監(jiān)聽上傳進度
咱們先使用axios實現監(jiān)聽上傳進度如下:
axios.post('/api/file/uploadfile', form, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent) => {
if (progressEvent.lengthComputable) {
this.progresss = Math.round((progressEvent.loaded / progressEvent.total) * 100);
}
},
})
.then((res) => {
// ...
});前端使用ajax獲取上傳進度
前端使用ajax如何獲取上傳進度呢? 如下:
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const progressPercentage = Math.round((event.loaded / event.total) * 100);
console.log(`上傳進度: ${progressPercentage}%`);
}
});前端使用fetch API獲取上傳進度
如何使用fetch API獲取上傳的進度呢?如下:
const file = document.getElementById('fileInput').files[0];
fetch('/upload', {
? method: 'POST',
? body: file,
? onprogress: (event) => {
? ? if (event.lengthComputable) {
? ? ? const progressPercentage = Math.round((event.loaded / event.total) * 100);
? ? ? console.log(`上傳進度: ${progressPercentage}%`);
? ? }
? },
})
? .then((response) => {
? ? // 處理響應結果
? })
? .catch((error) => {
? ? // 處理錯誤
? });上面幾種都是獲取上傳進度展示的進度條。那么咱們還有那些展示進度條的方式呢?
多文件上傳展示一個進度條
如果支持多個文件上傳,并已文件上傳個數展示進度條的話,一般都是怎么做的呢?
需要考慮多個文件比如10個文件,在你上傳完第一個的時候進度條需要控制再10%以下,依此類推。如下面一塊代碼:
let progress = 0;
const UPLOAD_TYPE_MAP = {
? UPLOADING: 'uploading',
? COMPLATE: 'complate',
}
const files = [{ file:'', status: UPLOAD_TYPE_MAP.UPLOADING }, { file:'', status: UPLOAD_TYPE_MAP.UPLOADING }];
for (let index = 0; index < files.length; index++) {
? const element = files[index];
? // 1、這里是調接口的邏輯,可以是并行也可以完成一個調下一個,這個看你們的接口的限速吧,我就按照并行做了。
? // 2、這里是每個文件上傳完成的邏輯,更改當前文件的狀態(tài)把status 改成UPLOAD_TYPE_MAP.COMPLATE
}
const timer = setInterval(() => {
? const eachProgress = 100 / files.length; // 計算單個的比例
? const complateUpload = files.filter((item) => item.status === UPLOAD_TYPE_MAP.COMPLATE);
? const upperLimit = (complateUpload.length + 1) * eachProgress;
? const maxProgress = upperLimit > 100 ? 100 : upperLimit; // 計算出當前最大進度
? if(progress < maxProgress) {
? ? progress++; // 邊界控制
? }
? if(maxProgress === 100) {
? ? progress = 100;
? ? clearInterval(time);
? }
}, 500);上面就多文件展示一個進度條的具體代碼。其實不是很準確,文件有大有小,如果文件大小差不太多展示開可以。其實最好的方案是分別利用axios、ajax等分別展示一個進度條。還是看業(yè)務需求吧,
大文件分片上傳展示進度條
先簡單說下分片上傳的好處如下:
- 可靠性和魯棒性:將大文件分成小塊進行上傳,即使出現網絡中斷或其他意外情況,只需要重新上傳失敗的分片,而不需要重新上傳整個文件,提高上傳的可靠性和魯棒性。
- 傳輸效率:由于大文件被分成多個小塊進行并行上傳,可以充分利用網絡帶寬,提高傳輸速度和效率。
- 斷點續(xù)傳:如果上傳過程中斷,可以根據已成功上傳的分片信息,從上次中斷的地方繼續(xù)上傳,避免重復上傳已經上傳過的部分,節(jié)省時間和資源。
- 內存占用低:大文件一次性加載到內存中可能導致內存溢出,而分片上傳只需加載單個分片,減少了對內存的壓力,并適應內存有限的環(huán)境。
- 服務器負載平衡:使用分片上傳可以將上傳請求分散到多個服務器,降低單一服務器的負載壓力,提高整體系統(tǒng)的穩(wěn)定性和吞吐量。
- 靈活性:分片上傳允許用戶在任意時間暫停、取消或恢復上傳過程,提供了更好的用戶體驗和操作靈活性。
其實像咱們經常說別的網站為啥有的上傳速度這么快,我用的網速一樣我的為啥這么慢。其實還有就是看你們上傳的文件大小有沒有必要做分片上傳,畢竟沒有直接一個接口上傳開發(fā)快,前端、服務端都需要增加工作成本。那咱們下面先看下怎么實現分片如下:
// 定義分片大?。ㄒ宰止?jié)為單位) // 1MB
// 將文件切割為多個分片
function sliceFileIntoChunks(file, chunkSize = 1024 * 1024) {
? const fileSize = file.size;
? const chunks = Math.ceil(fileSize / chunkSize);
? const fileChunks = [];
? let start = 0;
? let end = chunkSize;
? for (let i = 0; i < chunks; i++) {
? ? const chunk = file.slice(start, end); // slice 可以把文件按照需要的大小分割
? ? fileChunks.push(chunk);
? ? start = end;
? ? end = start + chunkSize;
? }
? return fileChunks;
}獲取上傳進度(這個需求又回到了【多文件上傳展示一個進度條】上面)如下:
const files = sliceFileIntoChunks(originFile).map((item) => ({file: item, status: UPLOAD_TYPE_MAP.UPLOADING}));
// ... 忽略
const timer = setInterval(() => {
? const eachProgress = 100 / files.length; // 計算單個的比例
? const complateUpload = files.filter((item) => item.status === UPLOAD_TYPE_MAP.COMPLATE);
? const upperLimit = (complateUpload.length + 1) * eachProgress;
? const maxProgress = upperLimit > 100 ? 100 : upperLimit; // 計算出當前最大進度
? if(progress < maxProgress) {
? ? progress++; // 邊界控制
? }
? if(maxProgress === 100) {
? ? progress = 100;
? ? clearInterval(time);
? }
}, 500);有一個點需要注意你要告訴服務端你得切片索引,后面服務端還要合并切片呢?。?!。還有如果你們是按照大小切割的比如1M,你還要再上傳完成給服務端發(fā)送一個合并切片的通知。 如果你們是以份額切分的每次就分為10等份,那么這個上傳完成的請求你不再通知服務端也能判斷上。
結語
到此這篇關于JavaScript獲取上傳進度的幾種方式的文章就介紹到這了,更多相關JavaScript獲取上傳進度內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
利用js判斷瀏覽器類型(是否為IE,Firefox,Opera瀏覽器)
我們開發(fā)的人來說經常要加個判斷,要不可能某些功能沒法正常使用。要是沒加個判斷就會給大家?guī)硇┞闊?/div> 2013-11-11
JavaScript使用readAsDataURL讀取圖像文件
這篇文章主要為大家詳細介紹了JavaScript使用readAsDataURL讀取圖像文件的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05
JavaScript中數組Array.sort()排序方法詳解
本篇文章主要介紹了JavaScript中數組Array.sort()的排序方法。具有很好的參考價值,下面跟著小編一起來看下吧2017-03-03最新評論

