摘要:場景簡介由于業務需要,經常遇到下載各類文件的需求,其中最頭疼的莫過于前端下載圖片了,直接給個圖片文件地址會變成直接打開圖片,而不是彈窗提示另存為,研究了下前端實現文件下載最便捷的方法還是創建標簽,寫入屬性實現點擊下載,但這在瀏覽器上的實現又
場景簡介
由于業務需要,經常遇到下載各類文件的需求,其中最頭疼的莫過于前端下載圖片了,直接給個圖片文件地址會變成直接打開圖片,而不是彈窗提示另存為,研究了下前端實現文件下載最便捷的方法還是創建 a 標簽,寫入download 屬性實現點擊下載,但這在 ie 瀏覽器上的實現又與一般瀏覽器不同,于是摸索之后寫了個通用的下載方法,既可用來下載文件也可下載圖片,希望能夠幫到大家。npm 安裝使用
npm install --save ly-downloader使用時需傳入3個參數 download(type, data, name):
以 Vue 中組件使用為例type: 1 或 2( 用于判斷傳入的是地址還是canvas對象 )
data: type = 1 時傳入文件地址; type = 2 時傳入一個canvas對象( 配合html2canvas使用 )
name: 下載圖片默認文件名( type = 1 時設置""為地址默認文件名, type = 2 時 name 不能為空 )
注:name 參數雖然只有在下載文件類型為圖片時生效,但為避免出錯都需要傳入一個值
例:download(1, url, "") 或 download(2, canvas對象, "圖片附件")
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; } }好啦,希望該方法能夠解決大家在下載文件特別是圖片時遇到的問題 ^ - ^
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101204.html
摘要:所以實現小圖標時雪碧圖跟圖標字體會在一個網站共存,自定義圖標字體為什么比較耗時,且太復雜圖標無法實現請往下看開發流程就了解了。參考資料細談淺談圖標字體向下兼容優雅降級技術繪制小圖標技巧雪碧圖圖標字體矢量小圖標設計本文對應源碼源碼地址演示地址 showImg(https://segmentfault.com/img/bVRnAC?w=431&h=220); 之前寫了一篇關于雪碧圖的博文,...
摘要:標準模式的排版和運作模式都是以該瀏覽器支持的最高標準運行。這種合并外邊距的方式被稱為折疊,并且因而所結合成的外邊距稱為折疊外邊距。控制表單控件的禁用狀態。首先,巧妙的使用這一標記,將游覽器從所有情況中分離出來。 1.Doctype作用?標準模式與兼容模式各有什么區別 聲明位于位于HTML文檔中的第一行,處于?標簽之前。告知瀏覽器的解析器,用什么文檔標準解析這個文檔。DOCTYPE不存在...
摘要:搜索引擎中有一個爬蟲模塊,在頁面中使用諸如等強調式的標簽,有利于,說白了就是有利于被搜索到。定位相對定位不影響元素本身特性不使元素脫離文檔流。定時器如果是由事件控制的,要先關再開,避免多次觸發而混亂。 CSS篇 注意:css注釋使用/ /,而不是或者//,否則很容易導致不明錯誤!!! div padding:內邊距。盒子內容與盒子邊框的距離設置,相當于給盒子加了厚度,使用此屬性后會改...
摘要:搜索引擎中有一個爬蟲模塊,在頁面中使用諸如等強調式的標簽,有利于,說白了就是有利于被搜索到。定位相對定位不影響元素本身特性不使元素脫離文檔流。定時器如果是由事件控制的,要先關再開,避免多次觸發而混亂。 CSS篇 注意:css注釋使用/ /,而不是或者//,否則很容易導致不明錯誤!!! div padding:內邊距。盒子內容與盒子邊框的距離設置,相當于給盒子加了厚度,使用此屬性后會改...
閱讀 2283·2021-09-30 09:47
閱讀 2211·2021-09-26 09:55
閱讀 2938·2021-09-24 10:27
閱讀 1535·2019-08-27 10:54
閱讀 960·2019-08-26 13:40
閱讀 2486·2019-08-26 13:24
閱讀 2411·2019-08-26 13:22
閱讀 1721·2019-08-23 18:38