JavaScript不同場(chǎng)景下的文件下載方案詳解
文件下載實(shí)踐方案匯總
前端開(kāi)發(fā)中 常用 到的下載方式:
- a標(biāo)簽下載(鏈接下載)
- fetch / axios / XMLHttpRequest 異步請(qǐng)求資源下載
- blob 下載
- FileSaver 第三方庫(kù)下載
除了以上幾種通用性方案,在JQuery時(shí)期還會(huì)經(jīng)常使用到 form
表單提交等方式,但是隨著Vue、React的興起,一般在進(jìn)行選型時(shí)便很少使用form表單提交的形式了。
方案1:a標(biāo)簽下載
簡(jiǎn)單下載方式,通過(guò)a標(biāo)簽的href屬性加載下載url,適合普通場(chǎng)景下的簡(jiǎn)單下載。
適合場(chǎng)景
- get 請(qǐng)求
- 返回為文件流 / 返回URL
不適合場(chǎng)景
- 下載需要計(jì)算、權(quán)限驗(yàn)證、攜帶Cookie
- 需要?jiǎng)討B(tài)生成文件內(nèi)容,即需要Post傳參
- 需要處理跨域問(wèn)題
- 需要處理大文件下載(10M以上)
- 需要斷點(diǎn)續(xù)傳或文件下載進(jìn)度監(jiān)控等
應(yīng)用示例
<a download="demo">下載圖片</a>
function downLoadFile(res){ const ele = document.createElement('a'); ele.setAttribute('href',res.url); //設(shè)置下載文件的url地址 ele.setAttribute('download' , 'download');//用于設(shè)置下載文件的文件名 ele.click(); link.addEventListener('click', (event) => { event.preventDefault(); const downloadTimer = setTimeout(() => { alert('下載超時(shí),請(qǐng)重試!'); }, 5000); const errorListener = () => { clearTimeout(downloadTimer); alert('下載失敗!'); link.removeEventListener('error', errorListener); }; link.addEventListener('error', errorListener); }); } window.onload = function(){ $.ajax({ url:"api/file/download", type:"get", dataType:'JSON' }).then(function(res){ if(res.bizNO > 0 ){ downLoadFile(res); }else{ alert(res.bizMsg); } }).always(function(){ alert("連接異常"); }) }
擴(kuò)展說(shuō)明
關(guān)于優(yōu)先級(jí)
Causes the browser to treat the linked URL as a download. Can be used with or without a filename
value:
Without a value, the browser will suggest a filename/extension, generated from various sources:
The [Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition)
HTTP header → 上面的demo示例中,即使設(shè)置了dowmload屬性,由于響應(yīng)頭中包含 Content-Disposition:attachment;filename="neom-xDQKvPjxtxo-unsplash.jpg",所以下載圖片名稱(chēng)以響應(yīng)頭為準(zhǔn)
filename
: defining a value suggests it as the filename. /
and \
characters are converted to underscores (_
). Filesystems may forbid other characters in filenames, so browsers will adjust the suggested name if necessary.
關(guān)于響應(yīng)頭Content-Disposition
Content-Disposition
是一個(gè) HTTP 響應(yīng)頭,它指定了如何顯示響應(yīng)的內(nèi)容,特別是對(duì)于以附件形式下載的文件。這個(gè)頭部可以包含一個(gè)內(nèi)聯(lián)展示(inline)的選項(xiàng),也可以包含一個(gè)附件(attachment)的選項(xiàng),以及可選的文件名參數(shù)。
主要作用如下:
1.內(nèi)聯(lián)展示(inline)
- 如果
Content-Disposition
頭部的值設(shè)置為inline
,瀏覽器通常會(huì)嘗試在瀏覽器窗口內(nèi)顯示內(nèi)容,例如在瀏覽器中直接打開(kāi) PDF 文件或圖像。 - 這對(duì)于一些直接瀏覽的文件類(lèi)型是合適的。
2.附件下載(attachment)
- 如果
Content-Disposition
頭部的值設(shè)置為attachment
,瀏覽器通常會(huì)提示用戶(hù)下載文件,而不是直接在瀏覽器中顯示。 - 這對(duì)于需要用戶(hù)保存到本地的文件,如文檔、圖像、音頻和視頻等,是常見(jiàn)的設(shè)置。
3.指定文件名
通過(guò)filename
參數(shù),可以指定下載文件的文件名。這對(duì)于確保用戶(hù)下載的文件有一個(gè)明確的名稱(chēng)非常有用,而不是使用服務(wù)器上的默認(rèn)文件名。
例如,Content-Disposition: attachment; filename="example.txt"
。
方案2: Blob 下載
基礎(chǔ)概念
什么是blob
blob是File類(lèi)的超類(lèi),表示 二進(jìn)制大對(duì)象,是JS對(duì)不可修改二進(jìn)制數(shù)據(jù)的封裝類(lèi)型
blob相關(guān)知識(shí)點(diǎn)
developer.mozilla.org/zh-CN/docs/Web/API/Blob
適合場(chǎng)景
- 接口返回的格式為文件流格式
- 下載需要計(jì)算、權(quán)限驗(yàn)證、攜帶Cookie
- 需要?jiǎng)討B(tài)生成文件內(nèi)容,即需要Post傳參
代碼實(shí)現(xiàn)
function fileDownLoad(data){ // 1. 創(chuàng)建點(diǎn)擊下載的元素 var linkElement = document.createElement('a'); // 2. 判斷瀏覽器是否支持blob對(duì)象 try{ //該實(shí)例化的方式第一個(gè)參數(shù)必須是數(shù)組的格式 var blob = new Blob([data],{ type: "application/pdf" }); }catch(e){ //舊版本瀏覽器下的blob創(chuàng)建對(duì)象 window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; if(e.name == 'TypeError' && window.BlobBuilder){ var blobbuilder = new BlobBuilder(); BlobBuilder.append(data); var blob = blobbuilder.getBlob("application/pdf"); }else{ alert("瀏覽器版本較低,暫不支持該文件類(lèi)型下載"); } } // 提取blob文件中的url信息,使二進(jìn)制文件在不讀取到j(luò)s中時(shí)直接下載 let url = window.URL.createObjectURL(blob); linkElement.setAttribute('href',url); linkElement.setAttribute('downLoad','download'); linkElement.click(); // 釋放URL內(nèi)存 window.URL.revokeObjectURL(url); } document.querySelector('#fileInput').addEventListener('change', (event)=>{ fileDownLoad(event.target.files[0]) })
下載接口需要攜帶Cookie信息
function downloadFileWithToken(url, token) { let xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.setRequestHeader("Authorization", token); xhr.responseType = 'blob'; xhr.onload = function (e) { if (this.status === 200) { let blob = this.response; let fileName = '下載的文件名稱(chēng)'; // 針對(duì)IE瀏覽器 if (window.navigator.msSaveBlob) { try { window.navigator.msSaveBlob(blob, fileName); } catch (e) { console.log(e); } } else { // 通用瀏覽器 const url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(url); } } else { alert('下載文件失敗'); } } xhr.send(); }
方案3:FileSaver實(shí)現(xiàn)
基礎(chǔ)介紹
- FileSaver.js 是一個(gè)用于在客戶(hù)端保存文件的 JavaScript 庫(kù)
- github.com/eligrey/FileSaver.js
基礎(chǔ)使用
import FileSaver from 'file-saver' let blob = new Blob(["Hello, FileSaver! Blob 下載"], {type: "text/plain;charset=utf-8"}); window.saveAs(blob, "hello FileSaver.txt");
import FileSaver from 'file-saver' let blob = new Blob(["Hello, FileSaver! URL 下載"], {type: "text/plain;charset=utf-8"}); const url = window.URL.createObjectURL(blob) window.saveAs(url, "hello FileSaver.txt");
原理介紹
以上就是JavaScript不同場(chǎng)景下的文件下載方案詳解的詳細(xì)內(nèi)容,更多關(guān)于JavaScript文件下載的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Javascript實(shí)用方法之json合并的場(chǎng)景分析
這篇文章主要介紹了Javascript實(shí)用方法之json合并,jQuery 的“extend()”方法有兩個(gè)原型:合并的方法,分別是淺合并和深度合并,本文通過(guò)代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09JavaScript中實(shí)現(xiàn)PHP的打亂數(shù)組函數(shù)shuffle實(shí)例
這篇文章主要介紹了JavaScript中實(shí)現(xiàn)PHP的打亂數(shù)組函數(shù)shuffle實(shí)例,本文用2種方法實(shí)現(xiàn)了類(lèi)似PHP的打亂數(shù)組函數(shù)shuffle函數(shù),需要的朋友可以參考下2014-10-10GWT中復(fù)制到剪貼板 js+flash實(shí)現(xiàn)復(fù)制 兼容性比較好
今天看到有個(gè)Google Code的項(xiàng)目,叫ZeroClipboard,大意是使用flash作為媒介,將內(nèi)容復(fù)制到剪貼板。這比用純javascript好,因?yàn)椴煌瑸g覽器會(huì)出于安全的原因,有不同反應(yīng),例如IE會(huì)給出提示,有的瀏覽器不支持復(fù)制到剪貼板。2010-03-03
![JS數(shù)組降維的實(shí)現(xiàn)Array.prototype.concat.apply([], arr)](http://img.jbzj.com/images/xgimg/bcimg7.png)
JS數(shù)組降維的實(shí)現(xiàn)Array.prototype.concat.apply([], arr)

JS實(shí)現(xiàn)的緩沖運(yùn)動(dòng)效果示例

JavaScript初學(xué)者的10個(gè)迷你技巧