了解HTML/HTML5中的download属性

一、download属性是个什么鬼?

首先看下面这种截图:
下载按钮

如果我们想实现点击上面的下载按钮下载一张图片,你会如何实现?

我们可能会想到一个最简单的方法,就是直接按钮a标签链接一张图片,类似下面这样:

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

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

下载

看我的眼睛,go die

于是,基本上,目前的实现都是放弃HTML策略,而是使用,例如php这样的后端语言,通过告知浏览器header信息,来实现下载。

header('Content-type: image/jpeg'); 
header("Content-Disposition: attachment; filename='download.jpg'"); 

然而,这种前后端都要操心的方式神烦,现在都流行前后端分离,还搅在一起太累了,感觉不会再爱了。

那有没有什么只需要前端动动指头就能实现下载的方式呢?有,就是本文要介绍的download属性。

例如,我们希望点击“下载”链接下载图片而不是浏览,直接增加一个download属性就可以:

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

没错,你没有看错,就这么结束了,不妨点击后面的链接试试:下载

结果在Chrome浏览器下(FireFox浏览器因为跨域限制无效):
下载图片

不仅如此,我们还可以指定下载图片的文件名:

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

如果后缀名一样,我们还可以缺省,直接文件名:

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

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

Chrome下的截图效果示意:
下载同时更改名称

一个大写的酷里!

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

然而,caniuse展示的兼容性只是个笼统,根据鄙人的实地测试,事情要比看到的复杂。

主要表现在跨域策略的处理上,由于我手上没有IE13,所以,只能对比Chrome浏览器和FireFox浏览器:

如果需要下载的资源是跨域的,包括跨子域,在Chrome浏览器下,使用download属性是可以下载的,但是,并不能重置下载的文件的命名;而FireFox浏览器下,则download属性是无效的,也就是FireFox浏览器无论如何都不支持跨域资源的download属性下载。

而,如果资源是同域名的,则两个浏览器都是畅通无阻的下载,不会出现下载变浏览的情况。
FireFox浏览器下的下载提示

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

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

三、结束语

除了图片资源,我们还可以是PDF资源,或者txt资源等等。尤其Chrome等浏览器可以直接打开PDF文件,使得此文件格式需要download处理的场景越来越普遍。

此HTML属性虽然非常实用和方便,但是兼容性制约了我们的大规模应用。

同时考虑到很多时候,需要进行一些下载的统计,纯前端的方式想要保存下载量数据,还是有些吃紧,需要跟开发的同学配合才行,还不如使用传统方法。

所以,download属性的未来前景在哪里?当下是否可以直接加入到实际项目?还需要我们一起好好想想。其实使用JS实现download属性的polyfill并不难,但是,考虑到为何不所有浏览器都使用polyfill的方法,又觉得为了技术而技术是不太妥当的。

总之,先放着心上,再观察观察。

补充于2017-07-04
如果需求是直接使用JS触发浏览器的下载,可以看看这篇文章:“使用JS让文本字符串作为html或JSON文件下载”。

(本篇完)

分享到:

标签: , , ,

赞助商推荐(我也要赞助)

想学到点真东西? ×
如果你有1~3年前端开发经验,不妨 ×
想要工资30K? ×


发表评论(目前42 条评论)

  1. 谷歌download下载出现:下载失败-网络错误说道:

    谷歌浏览器通过a标签的download属性下载图片,出现下载失败-网络错误。。。前辈有没有遇到过解决过呀?求指教~~~~

  2. 尼克陈说道:

    棒啊 又帮到我的一个需求

  3. ig 照片下載说道:

    移动端统统不兼容

  4. 静默说道:

    在微信中无法使用download属性

  5. 说道:

    移动端(主要是安卓)怎么下载?点击没有反应

  6. Jun说道:

    大神,最近在遇到一个问题,在所有浏览器都可以,但是好像safari不支持,我在stackflow搜了半天找不到解决方案,特来请教!
    谢啦!
    $http({
    url: ‘××××××××××××××××××××××××/’,
    method: “POST”,
    data: {‘date':day},
    headers: {
    ‘Content-type': ‘application/json’
    },
    responseType: ‘arraybuffer’
    }).success(function (data, status, headers, config) {
    var headerType = ‘application/zip’,fileType = ‘-GMT.zip';
    if(headers()[‘content-type’]==’application/vnd.openxmlformats-officedocument.spreadsheetml.sheet’){
    headerType = “application/vnd.openxmlformats-officedocument.spreadsheetml.sheet”;
    fileType = “-GMT.xlsx”;
    }
    var blob = new Blob([data], {type: headerType});
    var objectUrl = URL.createObjectURL(blob);
    var a = document.createElement(“a”);
    document.body.appendChild(a);
    a.download = “×××××××××××”+ day +fileType;
    a.href = objectUrl;
    a.click();
    a.remove();
    //window.open(objectUrl);
    //FileSaver.saveAs(data);
    }).error(function (data, status, headers, config) {
    ××××

    });

  7. Lili说道:

    请问您说还不如使用传统方法 那传统方法是什么??

    • 小庞说道:

      我想你要的答案就是这个吧?我也是在别的群里看到相关问题然后百度过来得,看来download还得等等普及了才能用啊。这是那个老方法得链接,你看看吧http://www.xiaoxiaohan.com/php/3.html(别人写的)
      ====来自一只小菜鸟

  8. lee说道:

    火狐下载下来没有后缀怎么破

  9. llllllllllll说道:

    好像是href是绝对路径就不行

  10. llllllllllll说道:

    发现用了download直接点击下载,是会用原来文件名的,除非是,右键,链接另存为,才会使用download的参数做为文件名。。。

    • 阳阳说道:

      同感,IE不支持,chrome和360浏览器右键,链接另存为,才会使用download的参数做为文件名;firefox是支持的

  11. 不知不觉说道:

    在pc上确实可以下载,但是在手机上好像是在新窗口打开了图片诶,大神,这个怎么解决

  12. HEarTache psR.说道:

    哈哈,觉得前辈应该是个蛮开朗的逗x.
    原谅对前辈如此模糊仓促的评价, 学习一个技术看到了前辈发的一篇Blog,追到了这里,初看前辈头像, 我擦 跟老家的邻家大哥兼逗x连坐太像了。 之后又看到了前辈是09集华中科技大的高材生, 曾经自己无限向往并为之倾覆心血的目标。 向往之久, 可最后还是因为一些琐事,未能达到自己的目标成了一生的遗憾。 初来乍到跟前辈打个招呼, 未来会长期光顾前辈的小窝学习。 啊你哦塞哟~

  13. trance说道:

    我就想问问 右侧一直跟着的蓝色大面包是个啥~~

  14. tony说道:

    想问你每次写的文章上展示的浏览器兼容性是通过什么工具去测试的?DEMO都去测过每个浏览器的兼容性吗

  15. 愤怒的老鸟说道:

    旭哥你在慕课上面relative那个课 relative单词错了

  16. 小白说道:

    感觉你写的前端知识好多,我觉得有必要一个一个的全部读完。

  17. 雪板烧说道:

    兼容性问题始终是个大问题!

  18. 66666说道:

    别的不说,牛逼送上

  19. 不新鲜的萝卜皮说道:

    发现个展示上的小问题,网站导航栏下面多了一个句号”。”

  20. aalouie说道:

    我很怀念张含韵

  21. 亚信朱威峰说道:

    兄弟,顶你啊!最近查找东西的时候总是搜到您的这个网站,今天翻看了下,您已经坚持了六年了,光是这份毅力就了不起,在这个充满浮躁的世界里,向您致敬!您对技术日益精湛的追求,值得我们这些后备学习!

    —-一个学了七年地质毕业就转行的小弟。

  22. 土鸡价格说道:

    HTML/HTML5中的download属性,没记错的话应该是加载吧

    • 小丫说道:

      download的是下载的意思,onload的才是加载的意思。除开前端常识,这也是英语单词的本意。

  23. 小泼墨说道:

    chrome,ff还好,但是在safari还有移动端的浏览器上,download兼容性还是太差

  24. gap year说道:

    前段时间,我还在弄这个问题,知道了download属性的方法。不过好像兼容有问题,ie没用

  25. 苏茂林说道:

    很赞,可以在新的项目里试试图片的下载

  26. muzuiget说道:

    第二个下载链接用 download=”” 在 Firefox 45 里还是会在浏览器打开的。

  27. Chitanda说道:

    前辈这里有个小问题:第二个截图的实例代码和图上的后缀名不一样。。一个是gif一个是jpeg..开始没反应过来