場景簡介
由于業(yè)務需要,經(jīng)常遇到下載各類文件的需求嫌褪,其中最頭疼的莫過于前端下載圖片了旦部,直接給個圖片文件地址會變成直接打開圖片祈搜,而不是彈窗提示另存為,研究了下前端實現(xiàn)文件下載最便捷的方法還是創(chuàng)建 a 標簽士八,寫入download 屬性實現(xiàn)點擊下載容燕,但這在 ie 瀏覽器上的實現(xiàn)又與一般瀏覽器不同,于是摸索之后寫了個通用的下載方法婚度,既可用來下載文件也可下載圖片蘸秘,希望能夠幫到大家。
npm 安裝使用
npm install --save ly-downloader
使用時需傳入3個參數(shù) download(type, data, name):
- type: 1 或 2( 用于判斷傳入的是地址還是canvas對象 )
- data: type = 1 時傳入文件地址蝗茁; type = 2 時傳入一個canvas對象( 配合html2canvas使用 )
- name: 下載圖片默認文件名( type = 1 時設置''為地址默認文件名, type = 2 時 name 不能為空 )
注:name 參數(shù)雖然只有在下載文件類型為圖片時生效醋虏,但為避免出錯都需要傳入一個值
例:download(1, url, '') 或 download(2, canvas對象, '圖片附件')
以 Vue 中組件使用為例
import download from 'ly-downloader'
export default {
methods: {
// url = '你的文件地址'
_download (url) {
download(1, url, '文件名')
},
}
}
思路簡介
- 創(chuàng)建 a 標簽,href 傳入文件地址哮翘,download 寫上文件名颈嚼,觸發(fā)點擊事件實現(xiàn)文件另存為(設置文件名對非圖片類型文件無效)
- 圖片類型文件使用地址下載會直接打開,需要將圖片地址利用 canvas 獲取 baase64 格式文件饭寺,再由 base64 轉(zhuǎn)換為 blob 類型阻课,最后利用URL.createObjectURL() 方法獲取 blob 文件的地址,此類型地址傳入 a 標簽可實現(xiàn)不打開直接下載
- type = 2 這種情況是個人經(jīng)常遇到頁面截圖下載的場景艰匙,配合插件html2canvas 來使用非常方便限煞,原理還是根據(jù) canvas 對象一步步轉(zhuǎn)換成 blob 對象
源碼
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = download;
/**
* 下載文件
*
* @export
* @param {*} type 設置接收數(shù)據(jù)類型 參數(shù) 1 或 2
* @param {*} data type為 1 時 data 為文件地址; type為 2 時 data 為canvas對象
* @param {*} name 當文件為圖片類型時需設置文件名
*/
function download(type, data, name) {
if (type == 1) {
var url = data;
// 通過地址判斷是否為圖片類型文件
var ext = url.slice(url.lastIndexOf('.') + 1).toLowerCase();
if (isImage(ext)) {
convertUrlToBase64(url).then(function (base64) {
var blob = convertBase64UrlToBlob(base64);
// 下載
if (myBrowser() == 'IE') {
window.navigator.msSaveBlob(blob, name + '.jpg');
} else {
var a = document.createElement('a');
a.download = name;
a.href = URL.createObjectURL(blob);
a.style.display = 'none'
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
});
} else {
var a = document.createElement('a');
a.download = name;
a.href = url;
a.style.display = 'none'
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
} else {
var dataURL = data.toDataURL('image/jpeg', 1.0);
var base64 = {
dataURL: dataURL,
type: 'image/jpg',
ext: 'jpg'
};
var blob = convertBase64UrlToBlob(base64);
// 下載
if (myBrowser() == 'IE') {
window.navigator.msSaveBlob(blob, name + '.jpg');
} else {
var _a = document.createElement('a');
_a.download = name;
_a.href = URL.createObjectURL(blob);
_a.style.display = 'none'
document.body.appendChild(_a);
_a.click();
document.body.removeChild(_a);
}
}
}
/**
* 將 base64 轉(zhuǎn)換位 blob 對象
* blob 存儲 2進制對象的容器
* @export
* @param {*} base64
* @returns
*/
function convertBase64UrlToBlob(base64) {
var parts = base64.dataURL.split(';base64,');
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; i++) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
/**
* 將圖片地址轉(zhuǎn)換為 base64 格式
*
* @param {*} url
*/
function convertUrlToBase64(url) {
return new Promise(function (resolve, reject) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.src = url;
img.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
var dataURL = canvas.toDataURL('image/' + ext);
var base64 = {
dataURL: dataURL,
type: 'image/' + ext,
ext: ext
};
resolve(base64);
};
});
}
// 判斷瀏覽器類型
function myBrowser() {
var userAgent = navigator.userAgent; //取得瀏覽器的userAgent字符串
if (userAgent.indexOf("OPR") > -1) {
return "Opera";
}; //判斷是否Opera瀏覽器 OPR/43.0.2442.991
if (userAgent.indexOf("Firefox") > -1) {
return "FF";
} //判斷是否Firefox瀏覽器 Firefox/51.0
if (userAgent.indexOf("Trident") > -1) {
return "IE";
} //判斷是否IE瀏覽器 Trident/7.0; rv:11.0
if (userAgent.indexOf("Edge") > -1) {
return "Edge";
} //判斷是否Edge瀏覽器 Edge/14.14393
if (userAgent.indexOf("Chrome") > -1) {
return "Chrome";
} // Chrome/56.0.2924.87
if (userAgent.indexOf("Safari") > -1) {
return "Safari";
} //判斷是否Safari瀏覽器 AppleWebKit/534.57.2 Version/5.1.7 Safari/534.57.2
}
// 判斷文件是否為圖片類型
function isImage(ext) {
if (ext == 'png' || ext == 'jpg' || ext == 'jpeg' || ext == 'gif' || ext == 'bmp') {
return true;
}
}