因爲業務須要,常常遇到下載各種文件的需求,其中最頭疼的莫過於前端下載圖片了,直接給個圖片文件地址會變成直接打開圖片,而不是彈窗提示另存爲,研究了下前端實現文件下載最便捷的方法仍是建立 a 標籤,寫入download 屬性實現點擊下載,但這在 ie 瀏覽器上的實現又與通常瀏覽器不一樣,因而摸索以後寫了個通用的下載方法,既可用來下載文件也可下載圖片,但願可以幫到你們。
npm install --save ly-downloader
- type: 1 或 2( 用於判斷傳入的是地址仍是canvas對象 )
- data: type = 1 時傳入文件地址; type = 2 時傳入一個canvas對象( 配合html2canvas使用 )
- name: 下載圖片默認文件名( type = 1 時設置''爲地址默認文件名, type = 2 時 name 不能爲空 )
注:name 參數雖然只有在下載文件類型爲圖片時生效,但爲避免出錯都須要傳入一個值
例:download(1, url, '') 或 download(2, canvas對象, '圖片附件')html
import download from 'ly-downloader' export default { methods: { // url = '你的文件地址' _download (url) { download(1, url, '文件名') }, } }
- 建立 a 標籤,href 傳入文件地址,download 寫上文件名,觸發點擊事件實現文件另存爲(設置文件名對非圖片類型文件無效)
- 圖片類型文件使用地址下載會直接打開,須要將圖片地址利用 canvas 獲取 baase64 格式文件,再由 base64 轉換爲 blob 類型,最後利用URL.createObjectURL() 方法獲取 blob 文件的地址,此類型地址傳入 a 標籤可實現不打開直接下載
- type = 2 這種狀況是我的常常遇到頁面截圖下載的場景,配合插件html2canvas 來使用很是方便,原理仍是根據 canvas 對象一步步轉換成 blob 對象
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = download; /** * 下載文件 * * @export * @param {*} type 設置接收數據類型 參數 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 轉換位 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 }); } /** * 將圖片地址轉換爲 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; } }