【澳门葡京】canvas元素内容生成图像文件,Chrome中拔取HTML5落实所有文件

了解HTML/HTML5中的download属性

2016/04/07 · HTML5 · 5
评论 ·
download

初稿出处:
张鑫旭(@张鑫旭)   

一、download属性是个什么样鬼?

率先看下边那种截图:
澳门葡京 1

一经我们想完成点击上边的下载按钮下载一张图片,你会怎么着落成?

咱俩可能会想到一个最简易的艺术,就是间接按钮a标签链接一张图纸,类似上边那样:

<a href=”large.jpg”>下载</a>

1
<a href="large.jpg">下载</a>

而是,想法虽好,实际效果却不是我们想要的,因为浏览器可以一贯浏览图片,由此,大家点击上面的“下载”链接,并是不下载图片,而是在新窗口直接浏览图片。

下载

看我的眼睛,澳门葡京 2

于是,基本上,近期的落实都是轻重倒置HTML策略,而是选取,例如php那样的后端语言,通过报告浏览器header信息,来兑现下载。

header(‘Content-type: image/jpeg’); header(“Content-Disposition:
attachment; filename=’download.jpg'”);

1
2
header(‘Content-type: image/jpeg’);
header("Content-Disposition: attachment; filename=’download.jpg’");

可是,那种光景端都要顾虑的艺术神烦,现在都流行前后端分离,还搅在协同太累了,感觉不会再爱了。

那有没有何样只须要前端动入手指就能促成下载的点子吗?有,就是本文要介绍的download属性。

诸如,大家期待点击“下载”链接下载图片而不是浏览,直接增添一个download特性就可以:

<a href=”large.jpg” download>下载</a>

1
<a href="large.jpg" download>下载</a>

科学,你从未看错,就那样截至了,不妨点击前边的链接试试:下载

结果在Chrome浏览器下(FireFox浏览器因为跨域限制无效):
澳门葡京 3

不仅如此,大家还足以指定下载图片的公文名:

<a href=”index_logo.gif” download=”_5332_.gif”>下载</a>

1
<a href="index_logo.gif" download="_5332_.gif">下载</a>

一旦后缀名一样,我们仍能缺省,直接文件名:

<a href=”index_logo.gif” download=”_5332_”>下载</a>

1
<a href="index_logo.gif" download="_5332_">下载</a>

截图为虚,操作为实:下载

Chrome下的截图效果示意:
澳门葡京 4

一个大写的酷里!

【Data URL】

准备干活

想要将canvas元素当前突显的内容生成为图像文件,我们首先要获得canvas中的数据,在HTML5
<canvas>【澳门葡京】canvas元素内容生成图像文件,Chrome中拔取HTML5落实所有文件。要素的正规中提供了toDataURL()的办法可以将canvas中的内容生成为指定格式的DataURL,使用办法如下:

// 假设有一个id为cvs的canvas元素
var dataurl = document.getElementById('cvs').toDataURL('image/png');

大家今日亟待将DataURL生成为一个png类型的图像文件,并且那个操作是在该地完结的,不要求服务器扶助扭转文书。以下提供三种方法:

短期以来,在做文件下载作用的时候都是前者通过ajax把须求变更的文书的内容参数传递给后端,后端通过Java语言将文件生成在服务器,然后回到一个文本下载的连年地址url。前端通过location.href
= url或者window.open(url),完结文件的下载。

前者如同在那几个历程中尚无发出哪些较大的法力,无非是殡葬请求和开拓页面的机能。在此往日就在寻觅那样的文件下载格局,今日毕竟在工作要求的压力下找到了对应的化解方案。

二、浏览器包容性和跨域策略

澳门葡京 5

可是,caniuse浮现的兼容性只是个笼统,依照鄙人的确切测试,事情要比见到的扑朔迷离。

珍重表现在跨域策略的拍卖上,由于自己手上没有IE13,所以,只可以相比Chrome浏览器和FireFox浏览器:

只要必要下载的资源是跨域的,包罗跨子域,在Chrome浏览器下,使用download特性是足以下载的,不过,并不可能重置下载的文件的命名;而FireFox浏览器下,则download属性是低效的,也就是FireFox浏览器无论怎样都不协理跨域资源的download属性下载。

而,借使资源是同域名的,则八个浏览器都是交通的下载,不会现出下载变浏览的情形。
澳门葡京 6

是不是支持download属性的监测
要监测当前浏览器是不是协助download属性,一行JS代码就可以了,如下:

var isSupportDownload = ‘download’ in document.createElement(‘a’);

1
var isSupportDownload = ‘download’ in document.createElement(‘a’);

摩登的HTML5浏览器中,已经支撑用Data URL(RFC2397)来引用“外部”资源了。

方法一 利用HTML5 <a>标签的download属性

在HTML5正规中,<a>标签拥有一个新的习性download,download属性用来指明该超链接指向的目的是相应被下载的文书,例如

<a href="http://www.jianshu.com" download>下载</a>

download属性可以被赋值,用来指明下载文件的名号,例如

<a href="http://www.jianshu.com" download="index.html">下载</a>

HTML与公事下载

即使愿意在前端直接出发某些资源的下载,最方便快速的办法就是行使HTML5原生的download属性,
例如:

<a href="large.jpg" download>下载</a>

但众所周知,假使纯粹利用HTML属性来促成文件的下载(而不是浏览器打开或浏览),对于动态内容,就不能够。

譬如说,我们对此页面进行分享的时候,希望享受图片是页面内容的实时截图,此时,那一个图片就是动态的,纯HTML明显无法满意大家的急需,借助JS和任何一些HTML5风味,例如,将页面元素转换到canvas上,然后在转成图片展开下载。

单只是成功图片的下载不可能满意普通工作的须求,对于事情需若是遥远不够的。

三、结束语

除却图片资源,我们还足以是PDF资源,或者txt资源等等。尤其Chrome等浏览器可以直接打开PDF文件,使得此文件格式要求download处理的气象更是普遍。

此HTML属性纵然万分实用和福利,可是包容性制约了俺们的广泛使用。

还要考虑到许多时候,须要进行部分下载的总计,纯前端的法门想要保存下载量数据,仍然有些吃紧,须要跟开发的同室合营才行,还不如选取传统形式。

所以,download特性的前程前景在哪个地方?当下是不是足以一直投入到骨子里项目?还亟需大家共同可以思考。其实接纳JS完成download特性的polyfill并简单,可是,考虑到为什么不持有浏览器都应用polyfill的措施,又觉得为了技术而技术是不太妥当的。

由此可见,先放着心上,再观望观望。

1 赞 3 收藏 5
评论

澳门葡京 7

譬如上面的链接,在HTML5浏览器中点击后,会转到一个新页面,突显“Hello Data
URL!”字样。

示例

明日,大家可以通过将DataURL赋值给a标签的href属性,并且应用download属性使其变动为可下载的图片。

var dataurl = document.getElementById('cvs').toDataURL('image/png');
var a = document.createElement('a');
a.href = dataurl;
a.download = "sample";
a.click();

借助HTML5 Blob已毕文件新闻文件下载

假使对Blob不打听,可以先看看张鑫旭的接头DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型一文。

原理其实很简单,大家可以将文件或者JS字符串借助Blob转换成二进制,然后,作为a元素的href属性,协作download属性,完成下载。

代码也相比较容易,如下示例(包容Chrome和Fire福克斯):

var funDownload = function(content, filename){
    // 创建隐藏的可下载链接
    var eleLink = document.createElement('a');
    eleLink.download = filename;
    eleLink.style.display = 'none';
    // 字符内容转变成blob地址
    var blob = new Blob([content]);
    eleLink.href = URL.createObjectURL(blob);
    // 触发点击
    document.body.appendChild(eleLink);
    eleLink.click();
    // 然后移除
    document.body.removeChild(eleLink);
};

内部,content指须求下载的公文或者字符串内容,filename指下载到系统中的文件名称。

[html] 
<a href=”data:text/plain,Hello Data URL!”>Hello</a> 
只要文本内容涵盖特殊字符如何做?Data
URL也是一种URL,也可以使用通用的URL转义编码:

兼容性

脚下唯有Chrome和FireFox接济download属性

借助Base64完成任一文件下载

对此非文本文件,也是足以一贯JS触发下载的,例如,假若我们想下载一张图纸,可以把那张图纸转换成Base64格式,然后下载。

代码示例:

var funDownload = function(domImg, filename){
    // 创建隐藏的可下载链接
    var eleLink = document.createElement('a');
    eleLink.download = filename;
    eleLink.style.display = 'none';
    // 图片base64地址
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    var width = domImg.natureWidth;
    var height = domImg.natureHeight;
    context.drawImage(domImg, 0, 0);
    // 如果是PNG图片,则context.toDataURL('image/png');
    eleLink.href = context.toDataURL('image/jpeg');
    // 触发点击
    document.body.appendChild(eleLink);
    eleLink.click();
    // 移除
    document.body.removeChild(eleLink);
};

连发是.html文件,.txt,.json等只要内容是文件的文本,都可以选择那种小技巧完结下载。

在Chrome浏览器下,模拟点击成立的a元素及时不append到页面中,也是可以触发下载的,可是在FireFox浏览器中却万分,因而,上边的funcDownload()方法有一个appendChild和removeChild的处理,就是为了包容FireFox浏览器。

[html] 
<a
href=”data:text/html;charset=utf8,%3Ch1%3E%E4%BD%A0%E5%A5%BD%3C/h1%3E”>URL
escaped</a> 
下面的事例都是纯文本数据。其实Data
URL也可以象征二进制数据,用Base64编码即可(当然URL转义也能兑现)。
上边是一个意味着GIF图片的Data URL(引用自RFC2397):

方法二 修改DataURL的Mime-type

即使大家一向将收获的DataURL赋值给a标签的href属性,在点击链接后浏览器只会在新窗口打开图片,并不会一向实施下载。我们可以修改DataURL的Mime-type为octet-stream,强制让浏览器下载。

三番五次说达成在下CSV文件的法门

大家通过ajax从后端请求到的数据一般都是json格式,也就是说须求把json数据转成csv格式的数量,经过查找终于找到了一个相比好用的json转csv的工具。

平素上演示代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Download</title>
    <link rel="stylesheet" href="">
</head>
<body>
    <div class="demo">
        <p><input type="button" value="作为test.html文件下载"></p>
    </div>
    <script src="json2csv.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript" charset="utf-8">
        // 示例数据
        var fields = ['car', 'price', 'color'];
        var myCars = [
          {
            "car": "Audi",
            "price": 40000,
            "color": "blue"
          }, {
            "car": "BMW",
            "price": 35000,
            "color": "black"
          }, {
            "car": "Porsche",
            "price": 60000,
            "color": "green"
          }
        ];
        // json数据转csv格式
        var csv = json2csv({ data: myCars, fields: fields });

        var eleButton = document.querySelector('input[type="button"]');

        // 下载文件方法
        var funDownload = function (content, filename) {
            var eleLink = document.createElement('a');
            eleLink.download = filename;
            eleLink.style.display = 'none';
            // 字符内容转变成blob地址
            var blob = new Blob([content]);
            eleLink.href = URL.createObjectURL(blob);
            // 触发点击
            document.body.appendChild(eleLink);
            eleLink.click();
            // 然后移除
            document.body.removeChild(eleLink);
        };

        if ('download' in document.createElement('a')) {
            // 作为test.html文件下载
            eleButton.addEventListener('click', function () {
                funDownload(csv, 'test.csv');    
            });
        } else {
            eleButton.onclick = function () {
                alert('浏览器不支持');    
            };
        }
    </script>
</body>
</html>

里面的json2csv.js文件可以在此处下载,或者获取源码。

[html] 
<a
href=”data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7″>Larry</a> 
也不是兼具的二进制文件格式都无法不编码,当实际数据不包蕴特殊字符的时候,不编码也是可以的:

示例

var dataurl = document.getElementById('cvs').toDataURL('image/png').replace("image/png", "image/octet-stream");
var tmpa = document.createElement('a');
a.href = dataurl;
a.target = "_blank";
a.click();
内容参考来源

1.下载功用首要参照张鑫旭的博客中的一片文章:小tip:JS前端创制html或json文件并浏览器导出下载;

2.json2cav的代码参考来源为:;

澳门葡京 8

[html] 
<a
href=”data:application/octet-stream,12345″>octet-stream</a> 
上边的链接都足以点右键“另存为”本地磁盘文件,那几个进程似乎普通下载远程文件的操作一样。
那样的话,理论上大家得以将其它数据转发为一个Data
URL链接,以便让用户“下载”。

兼容性

其一措施对于大多数主流浏览器都可用,然则octet-stream并不分包文件名和扩张名的音讯,所以使用那些方法下载下来的文件是未曾伸张名的文书,浏览器可能默许的命名为“下载”或者“unknown”

【自动下载和默许文件名】
地点已经落到实处了转移文书数量并保存到当地的功效,不过还有不足:

对此浏览器可以显得的MIME类型,点击链接的话会直接在浏览器中展示,比如纯文本、HTML以及图片等项目。

若手动将链接另存,Chrome
22中文版弹出的保留框默认主文件名永远为“下载”,Firefox
16则是一串莫明其妙并以.part结尾的字符串做默许名。

对于浏览器不可以突显的MIME类型,Chrome 22和Firefox
16都会活动调用下载功效。可是Chrome普通话版下载的默许主文件名仍旧总为“下载”,Firefox
16则依旧莫明其妙的字符串。

可是,Chrome
22中曾经对<a>元素增加了一个新的价签属性“download”来化解这几个难点。

[html] 
澳门葡京 ,<a href=”data:text/plain,Hello Data URL!”
download=”hello.txt”>hello</a> 
<a
href=”data:text/html;charset=utf8,%3Ch1%3E%E4%BD%A0%E5%A5%BD%3C/h1%3E”
download=”URL escaped.html”>URL escaped</a> 
<a
href=”data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7″
download=”Larry.gif”>Larry</a> 
<a href=”data:application/octet-stream,12345″
download=”octet-stream.bin”>octet-stream</a> 
对于指定了download标签属性的链接,点击后,Chrome
总是会进行下载操作,并且下载保存的默许文件名即为download的属性值。
遗憾的是Firefox 16还不接济这样的特性。

其它,Chrome下载默许不升迁文件保留地方和名称。若希望每一回都唤醒,可在Chrome的装置中修改。

【附】

以往要在浏览器中贯彻那样一个另存为的功效,可以用IE的document.execCommand(‘SaveAs’)模拟,不过对复杂的多少格式就抓耳挠腮处理了。

照旧协作服务端程序可以处理千丝万缕的数码,但处理进程也变复杂了,纯粹的本地使用还非得搭建一个外加的服务器。

再不怕拔取HTA+FSO/ADO.Stream来变化文书,可是各代Windows系统中没用联合完善的通用对话框控件来落成“另存为”对话框,要么单独登记,要么使用Office中的对话框组件,或者其它措施模拟落成,结果那一个非主题功效造成整个完成复杂了许多。

对此更扑朔迷离的多少,Data URL可能不太够用,那时可以设想成效更强大的HTML5
File API,使用createObjectURL()方法可以收获比Data
URL更短的URL,那里不作具体描述。

至于Chrome
22支撑的<a>的竹签属性download,我是从“zip.js”(一个开源的zip压缩解压JS库)的demo中发现的。完毕此属性最早的Chrome版本未知。

URL】 最新的HTML5浏览器中,已经辅助用Data
URL(RFC2397)来引用外部资源了。
比如上面的链接,在HTML5浏览器中点击后,会转到一个新…

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website