HTML5+CSS3从入门到精通之HTML5 中的 download 属性
小职 2020-10-14 来源 :https://juejin.im/post/6883307101737713678 阅读 1586 评论 0

摘要:download是 HTML5 中标签新增的一个属性,本篇介绍了HTML5+CSS3从入门到精通之HTML5 中的 download 属性,希望对HTML5的相关学习有更深入的了解。

download是 HTML5 中<a>标签新增的一个属性,本篇介绍了HTML5+CSS3从入门到精通之HTML5 中的 download 属性,希望对HTML5的相关学习有更深入的了解。

HTML5+CSS3从入门到精通之HTML5 中的 download 属性

download是 HTML5 中<a>标签新增的一个属性,此属性会强制触发下载操作,指示浏览器下载 URL 而不是导航到它,并提示用户将其保存为本地文件,例如:

<a href="result.png" download>download</a>

如果缺少download属性,点击 "download" 会直接变成预览图片,当添加download属性后则会触发图片的下载。

文件命名问题

download属性不仅可以触发下载,也能指定下载文件名:

<a href="test.png" download="joker.png">下载</a>

如果下载文件的后缀与源文件保持一致,可以设置缺省文件名:

<a href="test.png" download="joker">下载</a>

动态资源下载

面对一些动态内容下载的业务场景,即图片等资源的地址并不是固定的(例如一些在线绘图工具所生成的图片),只使用 HTML 无法满足需求。为了能够满足不同的 URL 下载,可以通过JS 实现一个动态触发 URL 下载的方法。

function download(href, filename='')  {
 const a = document.createElement('a')
 a.download = filename
 a.href = href
 document.body.appendChild(a)  
 a.click()
 a.remove()
}

需要注意的是,代码中对创建的<a> 进行的 appendChild 和 remove 操作主要是为了兼容 FireFox 浏览器,在 FireFox 浏览器下调用该方法如果不将创建的<a>标签添加到 body 里,点击链接不会有任何反应,无法触发下载,而在 Chrome 浏览器中则不受此影响。

上述的方法可以实现同源资源的下载。但在很多场景中,还需要处理跨域资源。遗憾的是,download属性目前仅适用于同源 URL,即如果需要下载的资源地址是跨域的,**download**属性就会失效,如果浏览器能直接打开资源(比如图片,视频等)点击链接会变成导航预览。

Blob: URL

关于download属性还有介绍:

尽管 HTTP URL 需要位于同一源中,但是可以使用 blob: URL 和 data: URL ,以方便用户下载使用 JavaScript 生成的内容(例如使用在线绘图 Web 应用程序创建的照片)。

Blob(Binary Large Object)即二进制大对象,这个我们并不陌生,一些数据库将Blob用来表示存储二进制文件的字段类型。File 接口也是基于 Blob,继承了 Blob 的功能并将其扩展使其支持用户系统上的文件。Blob 对象通过 Blob 构造函数来创建:

Blob(blobParts[, options])

var debug = {hello: "world"};
var blob = new Blob([JSON.stringify(debug, null, 2)],
 {type : 'application/json'});

如果需要实现一些简单的文本或 JS 字符串之类的文件下载,可以通过将文本信息转成 blob 二进制流,生成一个 Blob URL,配合download属性完成下载,代码如下。

const downloadText = (text, filename = '') {
 const a = document.createElement('a')
 a.download = filename
 const blob = new Blob([text], {type: 'text/plain'})  
 // text指需要下载的文本或字符串内容
 a.href = window.URL.createObjectURL(blob)
 // 会生成一个类似blob://localhost:8080/d3958f5c-0777-0845-9dcf-2cb28783acaf 这样的URL字符串
 document.body.appendChild(a)  
 a.click()
 a.remove()
}

这种 Blob URL 与常见的 HTTP URL 有什么区别呢?

Blob URL / Object URL是一种伪协议,可以让Blob和File对象用作图像和二进制数据下载链接等URL源。

浏览器在内部通过URL.createObjectURL()创建一个对 Blob 或 File 对象的特殊引用,生成的 Blob URL 只能在浏览器本地的单个实例和同一会话中使用,并且这个 URL 对象会在页面退出的时候被浏览器释放。

因此 Blob URL 并不能指向一个服务器资源,你无法在其它页面中打开它。同时由于编码格式有所差别,Blob URL 比起 Data URLs 所占的空间资源更少,性能也更好。

Blob 为 Web 开发提供了一个非常有用的功能:创建 Blob URL。将二进制数据封装为 Blob 对象,然后使用URL.createObjectURL()生成 Blob URL,由于Blob URL本身就是一个同源URL,可以使用该 URL 配合download解决跨域资源的下载以及命名问题

解决办法

通过 Blob 和 Fetch 可以解决跨域和文件命名的问题:使用fetch获取跨域资源返回一个blob 对象并生成一个 Blob URL,配合<a>标签的download属性触发下载,代码如下:

function download(href, filename = '')  {
 const a = document.createElement('a')
 a.download = filename
 a.href = href
 document.body.appendChild(a)  
 a.click()
 a.remove()
}

function downloadFile(url, filename='') {
 fetch(url, {
   headers: new Headers({
     Origin: window.location.origin,
   }),
   mode: 'cors',
 })
   .then(res => res.blob())
   .then(blob => {
     const blobUrl = window.URL.createObjectURL(blob)
     download(blobUrl, filename)
     window.URL.revokeObjectURL(blobUrl)
   })
}

这样就可以将正常的图片下载到本地了。

需注意的是跨域资源所在的服务器需要配置 Access-Control-Allow-Origin 信息,否则会得到一个大写的跨域报错。header 配置例如:

// 允许任何域名访问
header('Access-Control-Allow-Origin: *');

//指定域名访问
header('Access-Control-Allow-Origin: https://h5.ele.me');

目前这种方法还存在一些不足,例如浏览器会限制 Blob 数据大小不超过500M,在性能方面也会有所不足。

总结

目前前端有很多种下载方法,download属性下载属于其中比较简单的一种,不过仔细考量其中的一些特性也能挖掘出很多有用的信息。download与浏览器特性紧密相关,目前该属性的兼容性也是一大问题,不过连微软官方都恳求用户不要再使用 IE ,相信以后download的兼容性问题会持续得到改善,应用前景也会越来越广阔。


关注“职坐标在线”公众号,免费获取最新技术干货教程资源哦!

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程