javascript前端实现base64图片下载(兼容IE10+,chrome,firefox)
不是不兼容ie,就是不兼容ff,费了很多时间感谢原作者.
背景
在项目开发过程中,经常会有图片导出的需求,尤其是带有图表类的应用,通常需要将图表下载导出。
在chrome等新版浏览器中实现base64图片的下载还是比较容易的:
- 创建一个a标签
- 将a标签的href属性赋值为图片的base64编码
- 指定a标签的download属性,作为下载文件的名称
- 触发a标签的点击事件
但是这套逻辑在IE下是不行的,这样写会直接报错。
所以IE下需要单独处理,这里IE在处理这种文件的时候给提供了一个单独的方法:window.navigator.msSaveOrOpenBlob(blob, download_filename)调用这个方法可以直接触发IE的下载,还是比较方便的。具体做法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 截取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,...'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <em id= "__mceDel" > // 如果浏览器支持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})); //兼容火狐 <br>}</em> |
不是不兼容ie,就是不兼容ff,费了很多时间感谢原作者.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <img name= "pic1" /> <input type= "button" value= "下载" onclick= "download('img1')" > <script> var ret= "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJ C4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/<br>wAARCAB+AGYDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0K<br>xwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDx<br>MXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBU<br>QdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqK<br>mqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD36iiigAooryj4k/Fo+HLmTSNFjSXUFAMk7EMkee2Ac7v8QfagTdj1Ka5t7<br>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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?