JavaScript不同場景下的文件下載方案詳解
文件下載實踐方案匯總
前端開發(fā)中 常用 到的下載方式:
- a標簽下載(鏈接下載)
- fetch / axios / XMLHttpRequest 異步請求資源下載
- blob 下載
- FileSaver 第三方庫下載
除了以上幾種通用性方案,在JQuery時期還會經(jīng)常使用到 form 表單提交等方式,但是隨著Vue、React的興起,一般在進行選型時便很少使用form表單提交的形式了。
方案1:a標簽下載
簡單下載方式,通過a標簽的href屬性加載下載url,適合普通場景下的簡單下載。
適合場景
- get 請求
- 返回為文件流 / 返回URL
不適合場景
- 下載需要計算、權限驗證、攜帶Cookie
- 需要動態(tài)生成文件內(nèi)容,即需要Post傳參
- 需要處理跨域問題
- 需要處理大文件下載(10M以上)
- 需要斷點續(xù)傳或文件下載進度監(jiān)控等
應用示例
<a
download="demo">下載圖片</a>
function downLoadFile(res){
const ele = document.createElement('a');
ele.setAttribute('href',res.url); //設置下載文件的url地址
ele.setAttribute('download' , 'download');//用于設置下載文件的文件名
ele.click();
link.addEventListener('click', (event) => {
event.preventDefault();
const downloadTimer = setTimeout(() => {
alert('下載超時,請重試!');
}, 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("連接異常");
})
}
擴展說明
關于優(yōu)先級
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示例中,即使設置了dowmload屬性,由于響應頭中包含 Content-Disposition:attachment;filename="neom-xDQKvPjxtxo-unsplash.jpg",所以下載圖片名稱以響應頭為準
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.
關于響應頭Content-Disposition
Content-Disposition 是一個 HTTP 響應頭,它指定了如何顯示響應的內(nèi)容,特別是對于以附件形式下載的文件。這個頭部可以包含一個內(nèi)聯(lián)展示(inline)的選項,也可以包含一個附件(attachment)的選項,以及可選的文件名參數(shù)。
主要作用如下:
1.內(nèi)聯(lián)展示(inline)
- 如果
Content-Disposition頭部的值設置為inline,瀏覽器通常會嘗試在瀏覽器窗口內(nèi)顯示內(nèi)容,例如在瀏覽器中直接打開 PDF 文件或圖像。 - 這對于一些直接瀏覽的文件類型是合適的。
2.附件下載(attachment)
- 如果
Content-Disposition頭部的值設置為attachment,瀏覽器通常會提示用戶下載文件,而不是直接在瀏覽器中顯示。 - 這對于需要用戶保存到本地的文件,如文檔、圖像、音頻和視頻等,是常見的設置。
3.指定文件名
通過filename參數(shù),可以指定下載文件的文件名。這對于確保用戶下載的文件有一個明確的名稱非常有用,而不是使用服務器上的默認文件名。
例如,Content-Disposition: attachment; filename="example.txt"。

方案2: Blob 下載
基礎概念
什么是blob
blob是File類的超類,表示 二進制大對象,是JS對不可修改二進制數(shù)據(jù)的封裝類型
blob相關知識點
developer.mozilla.org/zh-CN/docs/Web/API/Blob

適合場景
- 接口返回的格式為文件流格式
- 下載需要計算、權限驗證、攜帶Cookie
- 需要動態(tài)生成文件內(nèi)容,即需要Post傳參
代碼實現(xiàn)
function fileDownLoad(data){
// 1. 創(chuàng)建點擊下載的元素
var linkElement = document.createElement('a');
// 2. 判斷瀏覽器是否支持blob對象
try{
//該實例化的方式第一個參數(shù)必須是數(shù)組的格式
var blob = new Blob([data],{
type: "application/pdf"
});
}catch(e){
//舊版本瀏覽器下的blob創(chuàng)建對象
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("瀏覽器版本較低,暫不支持該文件類型下載");
}
}
// 提取blob文件中的url信息,使二進制文件在不讀取到js中時直接下載
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 = '下載的文件名稱';
// 針對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實現(xiàn)
基礎介紹
- FileSaver.js 是一個用于在客戶端保存文件的 JavaScript 庫
- github.com/eligrey/FileSaver.js
基礎使用
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不同場景下的文件下載方案詳解的詳細內(nèi)容,更多關于JavaScript文件下載的資料請關注腳本之家其它相關文章!
相關文章
JavaScript中實現(xiàn)PHP的打亂數(shù)組函數(shù)shuffle實例
這篇文章主要介紹了JavaScript中實現(xiàn)PHP的打亂數(shù)組函數(shù)shuffle實例,本文用2種方法實現(xiàn)了類似PHP的打亂數(shù)組函數(shù)shuffle函數(shù),需要的朋友可以參考下2014-10-10
GWT中復制到剪貼板 js+flash實現(xiàn)復制 兼容性比較好
今天看到有個Google Code的項目,叫ZeroClipboard,大意是使用flash作為媒介,將內(nèi)容復制到剪貼板。這比用純javascript好,因為不同瀏覽器會出于安全的原因,有不同反應,例如IE會給出提示,有的瀏覽器不支持復制到剪貼板。2010-03-03
JS數(shù)組降維的實現(xiàn)Array.prototype.concat.apply([], arr)
這篇文章主要介紹了JS數(shù)組降維的實現(xiàn)Array.prototype.concat.apply([], arr),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04

