不断写作,加速成长!这个是我参加「AdminJS日新的目标 · 10 月更文考验」第22天,查看更多活动规则
前面涉及的压缩文件下载还是很多应用领域的,那样前面压缩文件下载有多少种方法呢?每一种方法有哪些利弊呢?下面来一一介绍。
1. a 标识
根据a
标签的download
特性来达到压缩文件下载,这种方法是最简单,是我们比较常用的方法,先来说实例编码:
<a href="http://www.baidu.com" download="baidu.html">免费下载</a>
就上边的这一实例,大家立即下载,才发现是跳转了百度搜索的首页,并没确实下载文件。
由于a
标识免费下载只有免费下载同源的文档,假如是跨域请求文件,这儿包含照片、音频视频等媒体文件,全是浏览,也无法打开。
上边的代码是先通过撰写a
标识来达到压缩文件下载,大家还可以通过js
来达到,编码如下所示:
const a = document.createElement('a')
a.href = 'http://www.baidu.com'
a.download = 'baidu.html'
a.click()
性能和上边的一样,全是跳转百度搜索的首页,并没有下载文件。
这儿的重点是a
标签的download
特性,这一属性HTML5
新增加。
它的功能是特定下载的文件名,假如不特定,那样下载的文件名便会依据要求视频的Content-Disposition
来决定,要是没有Content-Disposition
,这样就会应用请求的URL
的后一部分做为文件夹名称。
2. window.open
上边应用a
标识的案例还可以通过window.open
来达到,实际效果是一样的,编码如下所示:
window.open('http://www.baidu.com', '_blank')
这儿的_blank
是特定开启的方法,假如不特定,这样就会在当前页开启,这儿特定_blank
,便是进新页面开启。
一样a
标签的download
特性都是可以使用的,编码如下所示:
window.open('http://www.baidu.com', '_blank', 'download=baidu.html')
不过这种方法是有偏差的,相比较于a
标识,这种方法不能下载.html
、.htm
、.xml
、.xhtml
等相关资料,所以这些文档能被当做html
文档来处理,因此会直接从当前页开启。
同时也不能下载跨域请求文件,终归是window.open
,并不是window.download
(window.download
是幻想)。
3. location.href
这种方法和window.open(url)
是一样的,编码如下所示:
location.href = 'http://www.baidu.com'
这种方法有着window.open
的所有缺点,所以才建议使用,这儿只作为掌握,所以才进行任何解读。
4. location.?别的特性
这儿的许多泛指的都是可以跳转页面的特性,例如location.assign
、location.replace
、location.reload
等,这种特性都是能够完成压缩文件下载的,编码如下所示:
location.assign('http://www.baidu.com')
location.replace('http://www.baidu.com')
location.reload('http://www.baidu.com')
这儿的location.reload
是有些特殊,它的功能是重新加载当前页,可是它也可以接纳一个主要参数,这一主要参数就是为了自动跳转页面,因此也可以实现压缩文件下载。
自然同location.href
一样,这种方法的缺陷都一样,并且还有归属于每一个特性本身的特点,这儿当作扩展知识,不进行任何解读。
5. XMLHttpRequest
这种方法也就是我们常说的ajax
免费下载,包含axios
、fetch
等都是一样的,编码如下所示:
const xhr = new XMLHttpRequest()
xhr.responseType = 'blob'
xhr.open('GET', 'http://www.baidu.com')
xhr.send()
xhr.onload = function () {
const blob = new Blob([xhr.response], { type: 'text/html' })
const a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = 'baidu.html'
a.click()
}
这里不讲和XMLHttpRequest
这方面的知识了,只讲和压缩文件下载有关的那一部分。
这儿关键的思路是当我们要求完成后,我们也会取得响应体的response
,这一response
是我们要下载内容,随后我们把它转化成blob
目标,再通过URL.createObjectURL
来创建一个url
,再通过a
标签的download
特性来达到压缩文件下载。
这儿重点知识就会有2个,一个是blob
目标,一个是URL.createObjectURL
。
留意:应用
xhr
要求必须设定responseType
为blob
,不然直接下载文件是错码,不能正常分析。上边的代码还可以在随意网站检测,必要时下载照片,留意改动
blob
的type
特性,要是没有跨域请求问题应当都可以的。
5.1 blob
以下是blob
对象界定,来源于MDN:
Blob
目标表明一个不能变、原始记录的类文件对象。它数据信息可以按照文字或二进制的文件格式开展载入,还可以转化成ReadableStream
来用以数据操作。
Blob
表明的不一定是JavaScript
原生态格式数据信息。File
插口根据Blob
,继承blob
的功效并把它拓展以支持用户系统里的文档。
blob
目标是html5
新增加目标,它的功能就是用来存放二进制数据的,例如照片、短视频、声频等,它使用方法如下所示:
/**
* @param {Array} array 二进制数据
* @param {Object} options 配置项
* @param {String} options.type 文件属性,它代表着就会被放进到 blob 里的二维数组视频的 MIME 种类。
* @param {String} options.endings 用以特定包括行结束符\n的字符串数组怎样被载入。默认transparent,表明不容易改动行结束符。还能够指定为native,表明会把\n转换成\r\n。
*/
const blob = new Blob([], { type: '' })
这儿关键关心的是type
特性,默认设置前提下,blob
目标是并没有type
属性,那么这样的Blob
就是一个无类别的Blob
,文档不容易损坏,可是难以被正常的鉴别。
5.2 URL.createObjectURL
下边来源于MDN:
URL.createObjectURL() 静态方法会创建一个 DOMString,主要包含一个表明主要参数中给的对象 URL。这一 URL 的生命周期和建立它对话框里的 document 关联。这个新的 URL 目标表明指定 File 目标或 Blob 目标。
用这种方法就是用来创建一个url
的,它的功能是把一个blob
对象转换成一个url
,这一url
可用于下载文件,还可以用来浏览文档,编码如下所示:
const url = URL.createObjectURL(blob)
这儿需注意,这一url
的生命周期和建立它对话框里的document
关联,换句话说,当我们document
被清理后,这一url
便会无效,所以我们需要在合适的时间消毁它,编码如下所示:
URL.revokeObjectURL(url)
返回大家刚刚下载的软件难题,我们都是根据blob
目标去解决,但我们的type
属性写死的,若是在文件属性是明确的情形下是没有问题的,可是如果这些插口便是下载文件的插口,文档有可能是各种类型,大家应该怎么处理?
这儿的并没有标准答案,第一个可以跟插口服务提供者协商解决,商议方案是不确定性的,第二就是利用response
的header
来获取文件的type
,都是我们应该说的:
const type = response.headers['content-type']
const blob = new Blob([response.data], { type })
这儿我们可以通过response
的header
来获得type
,然后建立blob
目标,这样就能正确下载文件了。
实际上content-type
也有可能是application/octet-stream
,这时候我们就要根据file-type
来获取文件的type
了。
下边的代码是由file-type
来获取文件的type
:
import {fileTypeFromStream} from 'file-type';
const type = await fileTypeFromStream(response.body);
const blob = new Blob([response.data], { type })
file-type
的应用可以参考一下这儿。
6. 汇总
上边的解决方案那么多,实际上终究还是落入a
标签上,所以无论是根据浏览器内嵌内容进行免费下载,还是用ajax
开展免费下载,压缩文件下载的终究还是浏览器个人行为。