欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

如何下載文件并使用Javascript將其壓縮在瀏覽器中

如何下載文件并使用Javascript將其壓縮在瀏覽器中,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

雨山網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。成都創(chuàng)新互聯(lián)從2013年創(chuàng)立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)

與其生成zip文件并從您的服務(wù)器進(jìn)行傳輸,不如下載數(shù)據(jù)并將其壓縮在瀏覽器中呢?

我最近從事一個(gè)副項(xiàng)目,該項(xiàng)目可根據(jù)用戶的請求生成報(bào)告。對(duì)于每個(gè)請求,我們的后端將生成一個(gè)報(bào)告,將其上傳到Amazon  S3存儲(chǔ),然后將其URL返回給客戶端。由于生成報(bào)告需要一些時(shí)間,因此將存儲(chǔ)輸出文件,并且服務(wù)器將通過請求參數(shù)來緩存其URL。如果用戶訂購相同的商品,則后端將返回現(xiàn)有文件的URL。

幾天前,我有一個(gè)新要求,我需要下載一個(gè)包含數(shù)百個(gè)報(bào)告的zip文件,而不是單個(gè)文件。我想到的第一個(gè)解決方案是:

  • 在服務(wù)器上準(zhǔn)備壓縮文件

  • 上傳到Amazon S3存儲(chǔ)

  • 給客戶端提供下載URL

但是此解決方案有一些缺點(diǎn):

  • 生成zip文件的邏輯非常復(fù)雜。我需要考慮為每個(gè)請求生成所有文件,或者在重用現(xiàn)有文件和生成新文件之間進(jìn)行組合。兩種方法似乎都很復(fù)雜。他們將花費(fèi)一些時(shí)間來處理,并且稍后需要大量的編碼,測試和維護(hù)。

  • 它無法利用我已經(jīng)構(gòu)建的功能。盡管zip文件是不同的報(bào)告集,但很可能大多數(shù)單個(gè)報(bào)告都是由較早的請求生成的。因此,雖然zip文件本身不太可能可重用,但單個(gè)文件卻可以重用。使用上述方法,我需要一直重做整個(gè)過程,這并不是很有效。

  • 生成一個(gè)zip文件需要很長時(shí)間。由于我的后端是一個(gè)單線程進(jìn)程,因此此操作可能會(huì)阻止其他請求一段時(shí)間,并且在此期間可能會(huì)超時(shí)。

  • 在客戶端跟蹤流程非常困難,我喜歡在網(wǎng)站上放置進(jìn)度欄。如果一切都在后端處理,我需要找到其他方法向前端報(bào)告狀態(tài)。這并不容易。

  • 我想節(jié)省基礎(chǔ)設(shè)施的成本。如果我們可以將一些計(jì)算轉(zhuǎn)移到前端并降低基礎(chǔ)架構(gòu)的成本,那就太好了。我的客戶不介意他們再等幾秒鐘,還是在筆記本電腦上花費(fèi)額外的MB  RAM。

我想出的最終解決方案是:將所有文件下載到瀏覽器中,然后將其壓縮。在這篇文章中,我將介紹如何做。

免責(zé)聲明:在這篇文章中,我假設(shè)你已經(jīng)具有有關(guān)Javascript和Promise的基本知識(shí)。如果你沒有,我建議你先了解他們,然后再回到這里:)

下載單個(gè)文件

在應(yīng)用新解決方案之前,我的系統(tǒng)允許下載一個(gè)報(bào)告文件。有很多方法可以做到這一點(diǎn),后端可以直接通過HTTP請求響應(yīng)原始文件的內(nèi)容,也可以將文件上傳到另一個(gè)存儲(chǔ)設(shè)備并返回文件URL。我選擇第二種方法,因?yàn)槲蚁刖彺嫠猩傻奈募?/p>

一旦有了文件URL,在客戶端上的工作就非常簡單:在新選項(xiàng)卡中打開此URL。瀏覽器將完成剩下的工作以下載文件。

const downloadViaBrowser = url => {     window.open(url, ‘_blank’); }

下載多個(gè)文件并存儲(chǔ)在內(nèi)存中

當(dāng)下載和壓縮多個(gè)文件時(shí),我們不能再使用上面的簡單方法。

  • 如果一個(gè)JS腳本試圖同時(shí)打開許多鏈接,瀏覽器會(huì)懷疑它是否是一個(gè)安全威脅,并警告用戶阻止這些行為。雖然用戶可以確認(rèn)繼續(xù),但這不是一個(gè)好的體驗(yàn)

  • 你無法控制下載的文件,瀏覽器管理文件內(nèi)容和位置

解決此問題的另一種方法是使用 fetch  來下載文件并將數(shù)據(jù)作為Blob存儲(chǔ)在內(nèi)存中。然后,我們可以將其寫入文件或?qū)⑦@些Blob數(shù)據(jù)合并為zip文件。

const download = url => {   return fetch(url).then(resp => resp.blob()); };

這個(gè)函數(shù)返回一個(gè)被解析為blob的promise。我們可以結(jié)合 Promise.all() 來下載多個(gè)文件。Promise.all()  將一次性完成所有的promise,如果所有的子promise都被解析,或者其中一個(gè)承諾出現(xiàn)錯(cuò)誤,則進(jìn)行解析。

const downloadMany = urls => {   return Promise.all(urls.map(url => download(url)) }

按X文件組下載

但是,如果我們需要一次下載大量文件怎么辦?假設(shè)有1000個(gè)文件?使用 Promise.all() 可能不再是一個(gè)好主意,你的代碼將一次發(fā)送一千個(gè)請求。  這種方法有很多問題:

  • 操作系統(tǒng)和瀏覽器支持的并發(fā)連接數(shù)是有限的。因此,瀏覽器一次只能處理幾個(gè)請求。其他請求放入隊(duì)列,并且超時(shí)計(jì)數(shù)。結(jié)果是,你的大多數(shù)請求在發(fā)送之前都會(huì)超時(shí)。

  • 一次發(fā)送大量請求也會(huì)使后端過載

我考慮過的解決方案是將文件分成多個(gè)組。假設(shè)我有1000個(gè)文件可供下載。而不是通過 Promise.all()  立即開始一次下載所有文件,我將每次下載5個(gè)文件。在完成這5個(gè)之后,我將開始另一個(gè)包,我總共會(huì)下載250個(gè)包。

要實(shí)現(xiàn)這個(gè)功能,我們可以做一個(gè)自定義邏輯。或者我建議一個(gè)更簡單的方法,就是利用第三方庫bluebirdjs。該庫實(shí)現(xiàn)了許多有用的Promise函數(shù)。在這個(gè)用例中,我將使用  Promise.map()。注意這里的Promise現(xiàn)在是庫提供的自定義Promise,而不是內(nèi)置的Promise。

import Promise from 'bluebird'; const downloadByGroup = (urls, files_per_group=5) => {   return Promise.map(     urls,      async url => {       return await download(url);     },     {concurrency: files_per_group}   ); }

通過上面的實(shí)現(xiàn),該函數(shù)將接收一個(gè)URL數(shù)組并開始下載所有URL,每次都具有最大  files_per_group。該函數(shù)返回一個(gè)Promise,它將在下載所有URL時(shí)解析,并在其中任何一個(gè)失敗時(shí)拒絕。

創(chuàng)建zip文件

現(xiàn)在我已經(jīng)把所有的內(nèi)容都下載到內(nèi)存中了。正如我上面提到的,下載的內(nèi)容被存儲(chǔ)為Blob。下一步是使用這些Blob數(shù)據(jù)創(chuàng)建一個(gè)壓縮文件。

import JsZip from 'jszip'; import FileSaver from 'file-saver'; const exportZip = blobs => {   const zip = JsZip();   blobs.forEach((blob, i) => {     zip.file(`file-${i}.csv`, blob);   });   zip.generateAsync({type: 'blob'}).then(zipFile => {     const currentDate = new Date().getTime();     const fileName = `combined-${currentDate}.zip`;     return FileSaver.saveAs(zipFile, fileName);   }); }

最終代碼

讓我們在這里完成我為此完成的所有代碼。

import Promise from 'bluebird'; import JsZip from 'jszip'; import FileSaver from 'file-saver'; const download = url => {   return fetch(url).then(resp => resp.blob()); }; const downloadByGroup = (urls, files_per_group=5) => {   return Promise.map(     urls,      async url => {       return await download(url);     },     {concurrency: files_per_group}   ); } const exportZip = blobs => {   const zip = JsZip();   blobs.forEach((blob, i) => {     zip.file(`file-${i}.csv`, blob);   });   zip.generateAsync({type: 'blob'}).then(zipFile => {     const currentDate = new Date().getTime();     const fileName = `combined-${currentDate}.zip`;     return FileSaver.saveAs(zipFile, fileName);   }); } const downloadAndZip = urls => {   return downloadByGroup(urls, 5).then(exportZip); }

總結(jié)

利用客戶端的功能有時(shí)對(duì)于減少后端的工作量和復(fù)雜性非常有用。

不要一次發(fā)送大量的請求。你會(huì)在前端和后端都遇到麻煩。相反,將作品分成小塊。

介紹一些第三方庫bluebird,jszip和file-saver。他們?yōu)槲夜ぷ鞯煤芎茫部赡軐?duì)您有幫助。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。

網(wǎng)站題目:如何下載文件并使用Javascript將其壓縮在瀏覽器中
文章分享:http://www.chinadenli.net/article30/pgdpso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)軟件開發(fā)網(wǎng)站內(nèi)鏈營銷型網(wǎng)站建設(shè)App設(shè)計(jì)手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司