同源單文件
針對單文件的情況下,同源的文件,可以通過 < a> 標籤的 download 屬性下載文件
const elt = document.createElement('a');
elt.setAttribute('href', url);
elt.setAttribute('download', 'file.png');
elt.style.display = 'none';
document.body.appendChild(elt);
elt.click();
document.body.removeChild(elt);
但是這個方案並不適用於非同源的資源,此時它相當於普通的超鏈接,點擊會跳轉到資源頁面,而不是下載。
非同源
如果不存在CORS問題, 可以藉助Blob實現下載(構造xhr請求文件地址, 以Blob的形式接收Response):
function downloadWithBlob(url) {
fetch(url).then(res => res.blob().then(blob => {
var a = document.createElement('a');
var url = window.URL.createObjectURL(blob);
var filename = 'file.png';
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
}));
}
如果存在CORS問題,可以考慮使用 canvas 將圖片轉換成 base64 編碼之後再通過 標籤的 download 屬性下載:
function downloadPic(url) {
const img = new Image;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
img.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0, 0);
const elt = document.createElement('a');
elt.setAttribute('href', canvas.toDataURL('image/png'));
elt.setAttribute('download', 'file.png');
elt.style.display = 'none';
document.body.appendChild(elt);
elt.click();
document.body.removeChild(elt);
};
img.crossOrigin = 'anonymous';
img.src = url;
}
如果有文件content
function funDownload(content, filename) {
// 創建隱藏的可下載鏈接
var eleLink = document.createElement('a');
eleLink.download = filename;
eleLink.style.display = 'none';
// 字符內容轉變成blob地址
var blob = new Blob([content]);
eleLink.href = URL.createObjectURL(blob);
// 觸發點擊
document.body.appendChild(eleLink);
eleLink.click();
// 然後移除
document.body.removeChild(eleLink);
};