这篇文章发布于 2016年04月6日,星期三,23:32,归类于 HTML相关。 阅读 189610 次, 今日 4 次 68 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=5332
一、download属性是个什么鬼?
首先看下面这种截图:
如果我们想实现点击上面的下载按钮下载一张图片,你会如何实现?
我们可能会想到一个最简单的方法,就是直接按钮a
标签链接一张图片,类似下面这样:
<a href="large.jpg">下载</a>
但是,想法虽好,实际效果却不是我们想要的,因为浏览器可以直接浏览图片,因此,我们点击下面的“下载”链接,并是不下载图片,而是在新窗口直接浏览图片。
看我的眼睛,
于是,基本上,目前的实现都是放弃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
属性下载。
而,如果资源是同域名的,则两个浏览器都是畅通无阻的下载,不会出现下载变浏览的情况。
是否支持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文件下载”。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=5332
(本篇完)
- JS字符串补全方法padStart()和padEnd()简介 (0.459)
- 原来浏览器原生支持JS Base64编码解码 (0.459)
- 给IE/Edge写了个textarea resize拉伸的polyfill (0.459)
- Polyfill吊炸天的CSS attr()新语法 (0.459)
- 巧借CSS var变量实现任意的CSS自定义语法 (0.459)
- 原来DOM还有toggleAttribute这样的JS API (0.459)
- Safari不支持build-in自定义元素的兼容处理 (0.459)
- polyfill、ponyfill、prollyfill傻傻分不清楚 (0.459)
- JS前端创建html或json文件并浏览器导出下载 (0.413)
- SVG <foreignObject>简介与截图等应用 (0.413)
- CSS页面重构之“门派”之分 (RANDOM - 0.075)
在最新的chrome浏览器下,同源下载文件,使用download属性也无法更改文件名了,请问有其他方式么
a标签下载无法在下载成功以后有一个提示,下载提示这一块有什么思路点拨一下的么
如何监听下载完成呢
# HTML5 download 执行条件
1. 同一个域名下的资源
2. http only
3. 绝对路径/相对路径 都可以
请问在webview里,这个功能不生效怎么办?比如在facebook里,想在网页生成图片并下载
github上搜download.js
现在chrome里面,跨域资源好像不能下载了
完整的url路径chrome 70.0.3538.77 不能下载,还没找到方法
本地图片可以实现下载,但是完整的路径 chrome 70.0.3538.102 是打开图片,不是下载。一度怀疑自己。
应该是下面所说的造成的
“抛开浏览器兼容性,还有几点限制:
href 所指向的地址,必须与当前网站同源,否则
chrome 65.0.3325.181 下测试,只能下载不能改名
chrome 69.0.3497.92 中已经严格遵循同源策略的限制,如果加载了非同源的内容,download 属性将失效,等效导航功能。
Firefox 61.0.1同上”
如果是其他域名下的文件download就会无视
前辈,您好 我在使用a标签下载mp3 格式文件的时候 为什么它并不执行下载 而是直接跳到一个新的页面播放了, 这种应该怎么解决啊
你好 我在新版65的chrome也遇到这个问题了,请问你解决了吗
你好,解决了吗?
我猜,是不是跨域了
确实是
兄弟,这个问题我也遇到了,请问你解决了吗,我试了好几个办法都不太行
Firefox可以通过打开about:config,将security.fileuri.strict_origin_policy一项的值修改为false以实现跨域下载。
同学 你是玩单机吗….自己下载自己的东西
谷歌浏览器通过a标签的download属性下载图片,出现下载失败-网络错误。。。前辈有没有遇到过解决过呀?求指教~~~~
棒啊 又帮到我的一个需求
移动端统统不兼容
支持。。。。
在微信中无法使用download属性
我也试了,是没办法的,你有什么解决方案么?
移动端(主要是安卓)怎么下载?点击没有反应
我也发现了这个问题,你解决了么,ios和pc端都可以
大神,最近在遇到一个问题,在所有浏览器都可以,但是好像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) {
××××
});
stackoverflow哈哈打漏了
请问您说还不如使用传统方法 那传统方法是什么??
我想你要的答案就是这个吧?我也是在别的群里看到相关问题然后百度过来得,看来download还得等等普及了才能用啊。这是那个老方法得链接,你看看吧http://www.xiaoxiaohan.com/php/3.html(别人写的)
====来自一只小菜鸟
传统方法是设置 Http Header,Content-Disposition: attachment
火狐下载下来没有后缀怎么破
好像是href是绝对路径就不行
发现用了download直接点击下载,是会用原来文件名的,除非是,右键,链接另存为,才会使用download的参数做为文件名。。。
同感,IE不支持,chrome和360浏览器右键,链接另存为,才会使用download的参数做为文件名;firefox是支持的
在pc上确实可以下载,但是在手机上好像是在新窗口打开了图片诶,大神,这个怎么解决
同问
哈哈,觉得前辈应该是个蛮开朗的逗x.
原谅对前辈如此模糊仓促的评价, 学习一个技术看到了前辈发的一篇Blog,追到了这里,初看前辈头像, 我擦 跟老家的邻家大哥兼逗x连坐太像了。 之后又看到了前辈是09集华中科技大的高材生, 曾经自己无限向往并为之倾覆心血的目标。 向往之久, 可最后还是因为一些琐事,未能达到自己的目标成了一生的遗憾。 初来乍到跟前辈打个招呼, 未来会长期光顾前辈的小窝学习。 啊你哦塞哟~
我就想问问 右侧一直跟着的蓝色大面包是个啥~~
谷哥哥的广告~
想问你每次写的文章上展示的浏览器兼容性是通过什么工具去测试的?DEMO都去测过每个浏览器的兼容性吗
caniuse.com
旭哥你在慕课上面relative那个课 relative单词错了
感觉你写的前端知识好多,我觉得有必要一个一个的全部读完。
兼容性问题始终是个大问题!
敢问download的兼容性改怎么解决啊?好苦恼
我也觉得download 兼容性有点差,而且火狐上面,还会默认打开视频。。。
别的不说,牛逼送上
发现个展示上的小问题,网站导航栏下面多了一个句号”。”
感谢反馈!
我很怀念张含韵
兄弟,顶你啊!最近查找东西的时候总是搜到您的这个网站,今天翻看了下,您已经坚持了六年了,光是这份毅力就了不起,在这个充满浮躁的世界里,向您致敬!您对技术日益精湛的追求,值得我们这些后备学习!
—-一个学了七年地质毕业就转行的小弟。
后辈
HTML/HTML5中的download属性,没记错的话应该是加载吧
download的是下载的意思,onload的才是加载的意思。除开前端常识,这也是英语单词的本意。
chrome,ff还好,但是在safari还有移动端的浏览器上,download兼容性还是太差
前段时间,我还在弄这个问题,知道了download属性的方法。不过好像兼容有问题,ie没用
很赞,可以在新的项目里试试图片的下载
第二个下载链接用 download=”” 在 Firefox 45 里还是会在浏览器打开的。
@muzuiget 没错,后面提到了,FireFox不支持跨域下载。
跨域和不跨域是否指代,资源的路径和网站源码是否在同一个服务器下。原谅我对跨域这个概念不是很清楚
Ie直接打开了
前辈这里有个小问题:第二个截图的实例代码和图上的后缀名不一样。。一个是gif一个是jpeg..开始没反应过来
@Chitanda 不用在意这些细节,我懒得换截图。
大神,我在做下载的时候, 文件小的时候可以成功,文件20m以上就挂了,您遇到过么
没
超过了a标签herf的长度限制,可以用blob的形式导出