最近遇到在浏览器中生成二维码,并将二维码转换成图片下载到本地的需求
总的来说,有以下几个步骤
-
字符串转换成二维码
这里可以使用插件 qrcode.js 生成,可以通过canvas
(IE9+) 和table
(IE8) 两种方式生成。$("#qrcode-container").empty().qrcode({ text: "http://www.baidu.com/" });
-
Canvas转换成Base64,然后转换成Blob对象
canvas
的toDataURL
方法可以将canvas转换成base64格式,再进一步生成Blob对象下载。因此在这一步,不支持Canvas的IE8就没办法生成base64了,而IE9也无法使用Blob对象,无法进行下一个步骤。var canvas = $("#qrcode-container").find("canvas")[0]; var base64Text = canvas.toDataURL("image/png"); var blob = getBlob(base64Text); function getBlob(base64) { var mimeString = base64.split(',')[0].split(':')[1].split(';')[0]; // mime类型 var byteString = atob(base64.split(',')[1]); //base64 解码 var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组 var intArray = new Uint8Array(arrayBuffer); //创建视图 for (i = 0; i < byteString.length; i += 1) { intArray[i] = byteString.charCodeAt(i); } return new Blob([intArray], { type: mimeString }); }
-
使用
URL.createObjectURL()
方法生成DOMString
,绑定到a
标签的href
属性中,利用a
标签的download
属性进行下载引用MDN的解释:
URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。
download
属性的解释MDN:此属性指示浏览器下载URL而不是导航到URL,因此将提示用户将其保存为本地文件。
如果属性有一个值,它将在保存提示中用作预先填写的文件名 (用户仍然可以根据需要更改文件名)。对允许的值没有限制,但是/和\被转换为下划线。大多数文件系统限制文件名中的一些标点符号,浏览器会相应地调整建议的名称。绑定到
a
标签的href
后,使用click
触发点击事件即可下载。注意IE、FireFox的使用的区别。var downloadFile = function(blob, fileName) { if(navigator.msSaveBlob) { // IE的Blob保存方法 navigator.msSaveBlob(blob, fileName); } else { var link = document.createElement('a'); var href = window.URL.createObjectURL(blob); link.href = href; link.download = fileName; document.body.appendChild(link); // firefox需要把a添加到dom才能正确执行click link.click(); // 延时保证下载成功执行,否则可能下载未找到文件的问题 setTimeout(function() { window.URL.revokeObjectURL(href); // 释放Url对象 document.body.removeChild(link); }, 100); } };
关于
URL.revokeObjectURL
方法在每次调用 createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法来释放。浏览器会在文档退出的时候自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。