浅析HTML5中的download特性应用

2021-02-22 21:27 jianzhan

伴随着前端开发技术性的发展趋势,愈来愈多的业务流程情景中必须前端开发来解决文档免费下载。在诸多的方式中,根据 <a> 标识的 download 特性完成免费下载是在其中普遍也是较为简易的1种方式。

download 特性详细介绍

基本的 <a> 标识根据 href 完成连接自动跳转,假如只想免费下载文档而并不是自动跳转预览,最好是的方法是在 <a> 标识中加上 download 特性,就可以很简易地完成免费下载实际操作。

download 是 HTML5 中 <a> 标识新增的1个特性,此特性会强制性开启免费下载实际操作,标示访问器免费下载 URL 而并不是导航栏到它,并提醒客户将其储存为当地文档,比如:

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

假如缺乏 download 特性,点一下 "download" 会立即变为预览照片,当加上 download 特性后则会开启照片的免费下载。

现阶段 download 特性的适配性如caniuse 中所展现的:

能够以看到,绝大多数流行的访问器基础都早已适用 download 特性,而 IE 的主要表现1如既往的感人,现阶段很多 Window 系统软件依然在应用 IE ,这也是很多业务流程要求必须考虑到的。这类适配性难题限定了 download 的更普遍运用。

动态性資源免费下载

应对1些动态性內容免费下载的业务流程情景,即照片等資源的详细地址其实不是固定不动的(比如1些线上制图专用工具所转化成的照片),只应用 HTML 没法考虑要求。以便可以考虑不一样的 URL 免费下载,能够根据JS 完成1个动态性开启 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> 开展的 appendChildremove 实际操作关键是以便适配 FireFox 访问器,在 FireFox 访问器下启用该方式假如不将建立的 <a> 标识加上到 body 里,点一下连接不容易有任何反映,没法开启免费下载,而在 Chrome 访问器中则不会受到此危害。

上述的方式能够完成同宗資源的免费下载。但在许多情景中,还必须解决跨域資源。遗憾的是, download 特性现阶段仅可用于 同宗 URL ,即假如必须免费下载的資源详细地址是跨域的, download 特性就会无效,点一下连接会变为导航栏预览。

检测:点一下免费下载,結果只是预览而没法免费下载照片。

注: Chrome65 以前是适用 download 特性开启文档跨域免费下载的,以后则严苛遵照同宗对策,没法再根据 download 特性开启跨域資源的免费下载。而 FireFox 1直不适用跨域資源的 download 特性免费下载。

文档取名难题

download 特性不但能够开启免费下载,也能特定免费下载文档名:

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

假如免费下载文档的后缀与源文档维持1致,能够设定缺省文档名:

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

笔者曾遇到过1个难题,根据 <a> 标识开启跨域資源免费下载,编码与上述的 download 方式基础同样,只是在设定 download 特性的地区有点不一样:

a.setAttribute(download, true)

結果在老版本号的 Chrome 访问器中出現了以下状况。

免费下载文档名变成 true 。很显著,访问器将 download 特性值读变成文档名。

历经剖析,出現上述难题关键是由于:

1. 最先本不应该将 download 设为 truedownloaddisabled 这类种类的特性值不一样,它与文档名立即有关联。并且针对这类前后左右端回应式免费下载的方法, download 特性其实不是必要的。

2. 在 Chrome 的初期版本号不但适用跨域資源的 download 特性免费下载,并且还能够根据 download 重设跨域資源的文档名,因而才会出現上述这类状况。

前后左右端相互配合进行文档免费下载的业务流程情景,1般是由后端开发设定回应头中的 Content-Disposition 信息内容来完成。

在 HTTP 情景中,Content-Disposition 第1个主要参数或是 inline(默认设置值,表明回应中的信息感受以网页页面的1一部分或全部网页页面的方式展现),或是 attachment(代表着信息体应当被免费下载到当地;大多数数访问器会展现1个“储存为”的会话框,将 filename 的值预填为免费下载后的文档名)。

假如在回应头中设定了 Content-Disposition ,前端开发也在对应连接的 <a> 标识中加上了 download 特性,那末此时取名标准:

假如 HTTP 头中的 Content-Disposition 特性授予了1个不一样于此特性的文档名,HTTP 头特性优先选择于此特性。

历经检测发现,当 HTTP 头中 Content-Disposition 不为空时:

在 Chrome 访问器中,无论 HTTP 头中 Content-Disposition 的第1个主要参数被设为 attachment 還是 inline ,要是设定了 filename, download 就没法重设文档名。相反,当 filename 为空时, download 特性值会被设为文档名。 在 FireFox 访问器中,访问器只会载入 Content-Disposition 的 filename 值,若是filename 为空,则取源文档名。此时 download 不管怎样都没法重设文档名。

总结1下: 未在回应头设定 Content-Disposition 信息内容(比如1般立即精准定位資源的同宗URL), download 特性能够重设文档名。若后端开发在 Content-Disposition 字段中早已设定了 filename,以 filename 值为准。

针对后端开发早已设置了文档名的状况下,假如依然要想对文档名开展重设,该怎样解决呢?

Blob: URL

有关 download 特性也有详细介绍:

虽然 HTTP URL 必须坐落于同1源中,可是可使用 blob: URL 和 data: URL ,以便捷客户免费下载应用 JavaScript 转化成的內容(比如应用线上制图 Web 运用程序流程建立的相片)。

Blob (Binary Large Object)即2进制大目标,这个大家其实不生疏,1些数据信息库将Blob用来表明储存2进制文档的字段种类。File 插口也是根据 Blob,承继了 Blob 的作用并将其拓展使其适用客户系统软件上的文档。Blob 目标根据 Blob 结构涵数来建立:

Blob(blobParts[, options])

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

假如必须完成1些简易的文字或 JS 标识符串之类的文档免费下载,能够根据将文字信息内容转成 blob 2进制流,转化成1个 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) 
  // 会转化成1个相近blob:http://localhost:8080/d3958f5c-0777-0845⑼dcf⑵cb28783acaf 这样的URL标识符串
  document.body.appendChild(a)  
  a.click()
  a.remove()
}

这类 Blob URL 与普遍的 HTTP URL 有甚么差别呢?

Blob URL / Object URL是1种伪协议书,可让Blob和File目标用作图象和2进制数据信息免费下载连接等URL源。

访问器在內部根据 URL.createObjectURL() 建立1个对 Blob 或 File 目标的独特引入,转化成的 Blob URL 只能在访问器当地的单独案例和同1对话中应用,而且这个 URL 目标会在网页页面撤出的情况下被访问器释放出来。

因而 Blob URL 其实不能指向1个服务器空间 ,你没法在其它网页页面中开启它。另外因为编号文件格式有一定的区别,Blob URL 比起 Data URLs 所占的室内空间資源更少,特性也更好。

Blob 为 Web 开发设计出示了1个十分有效的作用:建立 Blob URL。将2进制数据信息封裝为 Blob 目标,随后应用 URL.createObjectURL() 转化成 Blob URL,因为Blob URL自身便是1个同宗URL,可使用该 URL 相互配合 download 处理跨域資源的免费下载和取名难题。

处理计划方案

根据 Blob 和 Fetch 能够处理跨域和文档取名的难题:应用 fetch 获得跨域資源回到1个blob 目标并转化成1个 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: 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 信息内容,不然会获得1个大写的跨域出错。header 配备比如:

// 容许任何网站域名浏览
header('Access-Control-Allow-Origin: *');

//特定网站域名浏览
header('Access-Control-Allow-Origin: https://h5.ele.me');

现阶段这类方式还存在1些不够,比如访问器会限定 Blob 数据信息尺寸不超出500M,在特性层面也会有一定的不够。

总结

现阶段前端开发有许多种免费下载方式, download 特性免费下载属于在其中较为简易的1种,但是细心考虑在其中的1些特点也能发掘出许多有效的信息内容。 download 与访问器特点密不可分有关,现阶段该特性的适配性也是1大难题,但是连微软官方都乞求客户不必再应用 IE ,坚信之后 download 的适配性难题会不断获得改进,运用市场前景也会愈来愈宽阔。

以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。