示例下載接口url https://gold-cdn.xitu.io/extension/0.3.9/package.crx
javascript
window.open(url)
會打開一個新窗口,開始下載後會自動關閉新窗口。Safair 下載後沒有關閉新窗口。
Chrome、IE、Safair支持,貌似火狐不支持html
window.location=url
在當前窗口下載前端
Chrome、Safair支持java
iframe
function downloadByIframe (url) {
try {
const iframe = document.createElement('iframe');
iframe.src = url;
iframe.style.display = 'none';
document.body.appendChild(iframe);
} catch (e) {
}
}
複製代碼
<button onclick="downloadByIframe(url)">下載</button>
複製代碼
在HTML中,iframe 的屬性用src,但在JS中,只有部份瀏覽器支持修改src(讀是沒問題),真正通用的是要修改對應框架的href值。chrome
function changeIframeSrc (url) {
window.iframes['myIframe'].location.href = url;
}
複製代碼
<a href="url" download="filename">點擊連接下載</a>
function downloadByAElement (url, fileName) {
try {
const element = document.createElement('a');
element.href = url;
element.download = fileName;
const a = document.body.appendChild(element);
a.click();
document.body.removeChild(element);
} catch (e) {
}
}
downloadByAElement ('https://gold-cdn.xitu.io/extension/0.3.9/package.crx', 'test');
複製代碼
HTML5中給a標籤增長了一個download屬性,只要有這個屬性,點擊這個連接時瀏覽器就不在打開連接指向的文件,而是改成下載,目前只有chrome、firefox、opera、Edge支持。經常使用此方法點擊下載圖片。
IE既不支持a標籤的download屬性也不容許js調用a 標籤的click方法。json
<a>
標籤下載<a href="DataURI" download="filename">點擊連接下載</a>
segmentfault
function saveData2File (data, fileName) {
try {
const element = document.createElement('a');
cosnt uri = getDownloadUri(data);
element.href = uri;
element.download = fileName;
const a = document.body.appendChild(element);
cosnt evt = document.createEvent('HTMLEvents');
evt.initEvent('click', false, false); // 不加後面兩個參數在Firefox上報錯
a.dispatchEvent(evt);
document.body.removeChild(element);
} catch (e) {
}
}
複製代碼
注意: 瀏覽器對href屬性的URL長度有限制,若超過瀏覽器自身限制的最大長度會致使下載失敗。windows
瀏覽器 | 最大長度(字符數) | 備註 |
---|---|---|
IE | 2083 | 若是超過這個數字,提交按鈕沒有任何反應 |
Firefox | 65,536 | - |
Chrome | 8,182 | - |
Safari | 80,000 | - |
Opera | 190,000 |
Data URI Scheme
Data URI Scheme
是指能夠在Web 頁面中包含圖片但無需任何額外的HTTP 請求的一類URI。 Data URI Scheme
通常用於將通過base64編碼的數據嵌入網頁中,從而減小請求資源的連接數。IE8 以前的版本都不支持 data URI scheme
。後端
DataURI
的格式:data: [<mime-type>][;charset=<charset>][;<encoding>],<encoded data>
複製代碼
data:
協議名稱[<mime-type>]
可選項,數據類型,經常使用的有 image/png
, image/svg+xml
, text/plain
[;charset=<charset>]
可選項,源文本的字符集編碼方式。[<mime type>][;charset=<charset>]
的缺省值爲HTTP Header 中Content-Type的字段值;[;<encoding>]
數據編碼方式(有US-ASCII,BASE64 兩種),默認值爲US-ASCII,就是每一個字符會編碼爲%xx的形式,<encoded data>
編碼後的數據, 若是 <encoded data>
不是以 [;<encoding>]
方式編碼的數據,則會報異常DataURI
的方式encodeURIComponent
function getDownloadUri (data) {
const mimeType = 'attachment/csv';
const charset = ';charset=utf-8,';
const _utf = '\uFEFF'; // 爲了使文件以utf-8的編碼模式,同時也是解決中文亂碼的問題
return 'data:' + mimeType + charset + _utf + encodeURIComponent(data)
}
複製代碼
使用這種方式,當數據過多時,URI長度容易超出瀏覽器限制。 encodeURIComponent
經常使用來轉碼接口參數,爲了不服務器收到不可預知的請求,對任何用戶輸入的做爲URI部分的內容都須要用encodeURIComponent進行轉義。設計模式
URL.createObjectURL
URL.createObjectURL
的參數是File
對象或者Blob
對象
File
對象也就是經過input[type=file]
選擇的文件Blob
對象表示一個不可變、原始數據的類文件對象IE10如下不支持URL.createObjectURL
function getDownloadUri (data) {
const _utf = '\uFEFF'; // 爲了使文件以utf-8的編碼模式,同時也是解決中文亂碼的問題
if (window.Blob && window.URL && window.URL.createObjectURL) {
const blob = new Blob([_utf + data], {
type: 'text/json' // 寫本身須要的數據格式
});
return URL.createObjectURL(blob);
}
}
複製代碼
windows.navigator.msSaveBlob
IE10~Edge 專用msSaveBlob 是IE10~Edge 私有方法。
function downloadByMsSaveBlob (data) {
const _utf = '\uFEFF'; // 爲了使文件以utf-8的編碼模式,同時也是解決中文亂碼的問題
const blob = new Blob([_utf + data], {
type: 'text/json' // 本身須要的數據格式
});
navigator.msSaveBlob(_csvData, fileName);
}
複製代碼
execCommand
當一個HTML文檔切換到設計模式時,document暴露 execCommand 方法,該方法容許運行命令來操縱可編輯內容區域的元素。
有的資料有提到IE9可使用execCommand
方法來保存數據到本地文件,可是我本身沒有驗證過,不知道是否可行。並且MDN文檔中execCommand
沒有查到SaveAs
命令。這塊只是作個小記錄。
function saveFileByExecCommand (data, fileName) {
const newWindow = window.top.open('about:blank', '_blank');
newWindow.document.write('sep=,\r\n' + data);
newWindow.document.close();
newWindow.document.execCommand('SaveAs', false, fileName);
newWindow.close();
}
複製代碼
function saveData2File (data, fileName) {
const bw = getBrowser(); // 獲取瀏覽器信息
if (!bw['edge'] || !bw['ie']) {
const element = document.createElement('a');
cosnt uri = getDownloadUri(data);
element.href = uri;
element.download = fileName;
const a = document.body.appendChild(element);
cosnt evt = document.createEvent('HTMLEvents');
evt.initEvent('click', false, false); // 不加後面兩個參數在Firefox上報錯
a.dispatchEvent(evt);
document.body.removeChild(element);
} else if (bw['ie'] >= 10 || bw['edge'] === 'edge') {
const _utf = '\uFEFF'; // 爲了使文件以utf-8的編碼模式,同時也是解決中文亂碼的問題
const blob = new Blob([_utf + data], {
type: 'text/json' // 本身須要的數據格式
});
navigator.msSaveBlob(blob, fileName);
}
}
function getBrowser () {
const sys = {};
const ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('edge') !== -1) {
sys.edge = 'edge';
} else if (ua.match(/rv:([\d.]+)\) like gecko/)) {
sys.ie = ua.match(/rv:([\d.]+)\) like gecko/)[1];
} else if (ua.match(/msie ([\d.]+)/)) {
sys.ie = ua.match(/msie ([\d.]+)/)[1];
} else if (ua.match(/firefox\/([\d.]+)/)) {
sys.firefox = ua.match(/firefox\/([\d.]+)/)[1];
} else if (ua.match(/chrome\/([\d.]+)/)) {
sys.chrome = ua.match(/chrome\/([\d.]+)/)[1];
} else if (ua.match(/opera.([\d.]+)/)) {
sys.opera = ua.match(/opera.([\d.]+)/)[1];
} else if (ua.match(/version\/([\d.]+).*safari/)) {
sys.safari = ua.match(/version\/([\d.]+).*safari/)[1];
}
return sys;
}
複製代碼
參考資料: