JavaScript獲取上傳進(jìn)度的幾種方式實(shí)現(xiàn)
獲取上傳進(jìn)度的幾種方式
今天測(cè)試說(shuō)咱們的上傳后的等待界面都沒(méi)有l(wèi)oading, 看起來(lái)不像是等待界面需要優(yōu)化。然后產(chǎn)品說(shuō)參考下其他業(yè)務(wù)的上傳搞下吧。 我以為就一個(gè)loading的事,發(fā)現(xiàn)其他業(yè)務(wù)上傳使用的是環(huán)形、線形進(jìn)度條。我說(shuō)現(xiàn)在接口是沒(méi)有返回當(dāng)前進(jìn)度的,如果是以上傳完成后的文件數(shù)量(因?yàn)槲覀兪且粋€(gè)個(gè)文件上傳分批次調(diào)的接口)做判斷也不太準(zhǔn)確,因?yàn)槲募写笥行〉摹?/p>
后面就找另外一個(gè)前端同事聊了下他告訴我說(shuō)axios是有監(jiān)聽(tīng)整個(gè)上傳進(jìn)度api的,那我就針對(duì)文件上傳去了解了下做以下總結(jié):
前端使用axios實(shí)現(xiàn)監(jiān)聽(tīng)上傳進(jìn)度
咱們先使用axios實(shí)現(xiàn)監(jiān)聽(tīng)上傳進(jì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獲取上傳進(jìn)度
前端使用ajax如何獲取上傳進(jìn)度呢? 如下:
const xhr = new XMLHttpRequest(); xhr.upload.addEventListener('progress', (event) => { if (event.lengthComputable) { const progressPercentage = Math.round((event.loaded / event.total) * 100); console.log(`上傳進(jìn)度: ${progressPercentage}%`); } });
前端使用fetch API獲取上傳進(jìn)度
如何使用fetch API獲取上傳的進(jìn)度呢?如下:
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(`上傳進(jìn)度: ${progressPercentage}%`); ? ? } ? }, }) ? .then((response) => { ? ? // 處理響應(yīng)結(jié)果 ? }) ? .catch((error) => { ? ? // 處理錯(cuò)誤 ? });
上面幾種都是獲取上傳進(jìn)度展示的進(jìn)度條。那么咱們還有那些展示進(jìn)度條的方式呢?
多文件上傳展示一個(gè)進(jìn)度條
如果支持多個(gè)文件上傳,并已文件上傳個(gè)數(shù)展示進(jìn)度條的話,一般都是怎么做的呢?
需要考慮多個(gè)文件比如10個(gè)文件,在你上傳完第一個(gè)的時(shí)候進(jìn)度條需要控制再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、這里是調(diào)接口的邏輯,可以是并行也可以完成一個(gè)調(diào)下一個(gè),這個(gè)看你們的接口的限速吧,我就按照并行做了。 ? // 2、這里是每個(gè)文件上傳完成的邏輯,更改當(dāng)前文件的狀態(tài)把status 改成UPLOAD_TYPE_MAP.COMPLATE } const timer = setInterval(() => { ? const eachProgress = 100 / files.length; // 計(jì)算單個(gè)的比例 ? const complateUpload = files.filter((item) => item.status === UPLOAD_TYPE_MAP.COMPLATE); ? const upperLimit = (complateUpload.length + 1) * eachProgress; ? const maxProgress = upperLimit > 100 ? 100 : upperLimit; // 計(jì)算出當(dāng)前最大進(jìn)度 ? if(progress < maxProgress) { ? ? progress++; // 邊界控制 ? } ? if(maxProgress === 100) { ? ? progress = 100; ? ? clearInterval(time); ? } }, 500);
上面就多文件展示一個(gè)進(jìn)度條的具體代碼。其實(shí)不是很準(zhǔn)確,文件有大有小,如果文件大小差不太多展示開(kāi)可以。其實(shí)最好的方案是分別利用axios、ajax等分別展示一個(gè)進(jìn)度條。還是看業(yè)務(wù)需求吧,
大文件分片上傳展示進(jìn)度條
先簡(jiǎn)單說(shuō)下分片上傳的好處如下:
- 可靠性和魯棒性:將大文件分成小塊進(jìn)行上傳,即使出現(xiàn)網(wǎng)絡(luò)中斷或其他意外情況,只需要重新上傳失敗的分片,而不需要重新上傳整個(gè)文件,提高上傳的可靠性和魯棒性。
- 傳輸效率:由于大文件被分成多個(gè)小塊進(jìn)行并行上傳,可以充分利用網(wǎng)絡(luò)帶寬,提高傳輸速度和效率。
- 斷點(diǎn)續(xù)傳:如果上傳過(guò)程中斷,可以根據(jù)已成功上傳的分片信息,從上次中斷的地方繼續(xù)上傳,避免重復(fù)上傳已經(jīng)上傳過(guò)的部分,節(jié)省時(shí)間和資源。
- 內(nèi)存占用低:大文件一次性加載到內(nèi)存中可能導(dǎo)致內(nèi)存溢出,而分片上傳只需加載單個(gè)分片,減少了對(duì)內(nèi)存的壓力,并適應(yīng)內(nèi)存有限的環(huán)境。
- 服務(wù)器負(fù)載平衡:使用分片上傳可以將上傳請(qǐng)求分散到多個(gè)服務(wù)器,降低單一服務(wù)器的負(fù)載壓力,提高整體系統(tǒng)的穩(wěn)定性和吞吐量。
- 靈活性:分片上傳允許用戶在任意時(shí)間暫停、取消或恢復(fù)上傳過(guò)程,提供了更好的用戶體驗(yàn)和操作靈活性。
其實(shí)像咱們經(jīng)常說(shuō)別的網(wǎng)站為啥有的上傳速度這么快,我用的網(wǎng)速一樣我的為啥這么慢。其實(shí)還有就是看你們上傳的文件大小有沒(méi)有必要做分片上傳,畢竟沒(méi)有直接一個(gè)接口上傳開(kāi)發(fā)快,前端、服務(wù)端都需要增加工作成本。那咱們下面先看下怎么實(shí)現(xiàn)分片如下:
// 定義分片大?。ㄒ宰止?jié)為單位) // 1MB // 將文件切割為多個(gè)分片 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; }
獲取上傳進(jìn)度(這個(gè)需求又回到了【多文件上傳展示一個(gè)進(jìn)度條】上面)如下:
const files = sliceFileIntoChunks(originFile).map((item) => ({file: item, status: UPLOAD_TYPE_MAP.UPLOADING})); // ... 忽略 const timer = setInterval(() => { ? const eachProgress = 100 / files.length; // 計(jì)算單個(gè)的比例 ? const complateUpload = files.filter((item) => item.status === UPLOAD_TYPE_MAP.COMPLATE); ? const upperLimit = (complateUpload.length + 1) * eachProgress; ? const maxProgress = upperLimit > 100 ? 100 : upperLimit; // 計(jì)算出當(dāng)前最大進(jìn)度 ? if(progress < maxProgress) { ? ? progress++; // 邊界控制 ? } ? if(maxProgress === 100) { ? ? progress = 100; ? ? clearInterval(time); ? } }, 500);
有一個(gè)點(diǎn)需要注意你要告訴服務(wù)端你得切片索引,后面服務(wù)端還要合并切片呢?。?!。還有如果你們是按照大小切割的比如1M,你還要再上傳完成給服務(wù)端發(fā)送一個(gè)合并切片的通知。 如果你們是以份額切分的每次就分為10等份,那么這個(gè)上傳完成的請(qǐng)求你不再通知服務(wù)端也能判斷上。
結(jié)語(yǔ)
到此這篇關(guān)于JavaScript獲取上傳進(jìn)度的幾種方式的文章就介紹到這了,更多相關(guān)JavaScript獲取上傳進(jìn)度內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JS實(shí)現(xiàn)批量上傳文件并顯示進(jìn)度功能
- JS插件plupload.js實(shí)現(xiàn)多圖上傳并顯示進(jìn)度條
- js實(shí)現(xiàn)帶進(jìn)度條提示的多視頻上傳功能
- JS實(shí)現(xiàn)上傳文件顯示進(jìn)度條
- JS+html5實(shí)現(xiàn)異步上傳圖片顯示上傳文件進(jìn)度條功能示例
- 基于JS實(shí)現(xiàn)視頻上傳顯示進(jìn)度條
- 原生javascript上傳圖片帶進(jìn)度條【實(shí)例分享】
- 教你3分鐘利用原生js實(shí)現(xiàn)有進(jìn)度監(jiān)聽(tīng)的文件上傳預(yù)覽組件
- Node.js上傳文件功能之服務(wù)端如何獲取文件上傳進(jìn)度
- JavaScript實(shí)現(xiàn)監(jiān)控上傳和下載進(jìn)度
- Nodejs文件上傳、監(jiān)聽(tīng)上傳進(jìn)度的代碼
相關(guān)文章
js按條件生成隨機(jī)json:randomjson實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇js按條件生成隨機(jī)json:randomjson實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04JS實(shí)現(xiàn)簡(jiǎn)單獲取最近7天和最近3天日期的方法
這篇文章主要介紹了JS實(shí)現(xiàn)簡(jiǎn)單獲取最近7天和最近3天日期的方法,涉及javascript針對(duì)日期與時(shí)間的相關(guān)數(shù)值運(yùn)算與轉(zhuǎn)換操作技巧,需要的朋友可以參考下2018-04-04利用js判斷瀏覽器類型(是否為IE,Firefox,Opera瀏覽器)
我們開(kāi)發(fā)的人來(lái)說(shuō)經(jīng)常要加個(gè)判斷,要不可能某些功能沒(méi)法正常使用。要是沒(méi)加個(gè)判斷就會(huì)給大家?guī)?lái)些麻煩2013-11-11JavaScript使用readAsDataURL讀取圖像文件
這篇文章主要為大家詳細(xì)介紹了JavaScript使用readAsDataURL讀取圖像文件的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05使用TypeScript實(shí)現(xiàn)楊輝三角的代碼示例
楊輝三角,又稱帕斯卡三角,是一個(gè)數(shù)學(xué)上非常有趣和重要的概念,它是一種數(shù)學(xué)結(jié)構(gòu),它不僅可以用于組合數(shù)學(xué),還可以應(yīng)用于代數(shù)、概率和許多其他領(lǐng)域,在本文中,我們將通過(guò)使用?TypeScript?來(lái)編寫(xiě)楊輝三角的程序,同時(shí)深入探討?TypeScript?的類型系統(tǒng)2023-09-09JavaScript中數(shù)組Array.sort()排序方法詳解
本篇文章主要介紹了JavaScript中數(shù)組Array.sort()的排序方法。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-03-03從基礎(chǔ)開(kāi)始建立一個(gè)JS代碼庫(kù)
從基礎(chǔ)開(kāi)始建立一個(gè)JS代碼庫(kù),更新中 有心人會(huì)領(lǐng)技術(shù)走的更遠(yuǎn)2009-07-07關(guān)于base64編碼和解碼的js工具函數(shù)
這篇文章主要介紹了關(guān)于base64編碼和解碼的js工具函數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02