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