不是不兼容ie,就是不兼容ff,費了很多時間感謝原作者.
背景
在項目開發過程中,經常會有圖片導出的需求,尤其是帶有圖表類的應用,通常需要將圖表下載導出。
在chrome等新版瀏覽器中實現base64圖片的下載還是比較容易的:
- 創建一個a標簽
- 將a標簽的href屬性賦值為圖片的base64編碼
- 指定a標簽的download屬性,作為下載文件的名稱
- 觸發a標簽的點擊事件
但是這套邏輯在IE下是不行的,這樣寫會直接報錯。
所以IE下需要單獨處理,這里IE在處理這種文件的時候給提供了一個單獨的方法:window.navigator.msSaveOrOpenBlob(blob, download_filename)調用這個方法可以直接觸發IE的下載,還是比較方便的。具體做法如下:
// 截取base64的數據內容(去掉前面的描述信息,類似這樣的一段:data:image/png;base64,)並解碼為2進制數據 var bstr = atob(imgUrl.split(',')[1]) // 獲取解碼后的二進制數據的長度,用於后面創建二進制數據容器 var n = bstr.length // 創建一個Uint8Array類型的數組以存放二進制數據 var u8arr = new Uint8Array(n) // 將二進制數據存入Uint8Array類型的數組中 while (n--) { u8arr[n] = bstr.charCodeAt(n) } // 創建blob對象 var blob = new Blob([u8arr]) // 調用瀏覽器的方法,調起IE的下載流程 window.navigator.msSaveOrOpenBlob(blob, 'chart-download' + '.' + 'png')
整體代碼// 這里是獲取到的圖片base64編碼,這里只是個例子哈,要自行編碼圖片替換這里才能測試看到效果const imgUrl = 'data:image/png;base64,...'
// 如果瀏覽器支持msSaveOrOpenBlob方法(也就是使用IE瀏覽器的時候),那么調用該方法去下載圖片 if (window.navigator.msSaveOrOpenBlob) { var bstr = atob(imgUrl.split(',')[1]) var n = bstr.length var u8arr = new Uint8Array(n) while (n--) { u8arr[n] = bstr.charCodeAt(n) } var blob = new Blob([u8arr]) window.navigator.msSaveOrOpenBlob(blob, 'chart-download' + '.' + 'png') } else { // 這里就按照chrome等新版瀏覽器來處理 const a = document.createElement('a') a.href = URL.createObjectURL(blob);//imgUrl a.setAttribute('download', 'chart-download') //a.click() a.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));//兼容火狐
}
不是不兼容ie,就是不兼容ff,費了很多時間感謝原作者.
<img name="pic1" /> <input type="button" value="下載" onclick="download('img1')"> <script> var ret="/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJ C4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/
wAARCAB+AGYDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0K
xwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDx
MXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBU
QdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqK
mqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD36iiigAooryj4k/Fo+HLmTSNFjSXUFAMk7EMkee2Ac7v8QfagTdj1Ka5t7
fHnzxRZ6b3C5/Ouf1zx/wCGPDyn7fq8AkAB8qJvMcg9wo5r5K1TWdR1Wdpr+8nuZCS2ZXJxnrgdAPYUzS4BcXDJIPl2MR9cUrk8x77e/tA6HBftHbafd3NqpA80AKT9Aa7XRfiR"; document.all['pic1'].src = "data:image/jpg;base64," + ret; //下載圖片 function download(){ let imgData = "data:image/jpg;base64," + ret; this.downloadFile('測試.png', imgData); } //下載 function downloadFile(fileName, content) { let aLink = document.createElement('a'); let blob = this.base64ToBlob(content); //new Blob([content]); let evt = document.createEvent("HTMLEvents"); evt.initEvent("click", true, true);//initEvent 不加后兩個參數在FF下會報錯 事件類型,是否冒泡,是否阻止瀏覽器的默認行為 aLink.download = fileName; aLink.href = URL.createObjectURL(blob); // aLink.dispatchEvent(evt); aLink.click() } //base64轉blob function base64ToBlob(code) { let parts = code.split(';base64,'); let contentType = parts[0].split(':')[1]; let raw = window.atob(parts[1]); let rawLength = raw.length; let uInt8Array = new Uint8Array(rawLength); for (let i = 0; i < rawLength; ++i) { uInt8Array[i] = raw.charCodeAt(i); } return new Blob([uInt8Array], {type: contentType}); } </script>
參考引用
https://www.jb51.net/article/147431.htm