(1)第一种是后台放在服务器上面,然后前端直接访问就可以下载,此种前端不需要做额外的处理,可以用 type为download的a标签直接访问下载,也可以用window.open或location.href=""这种方式直接访问即可下载。
(2)第二种是前端访问接口,然后后端返回二进制文件。前端完成解析后下载。本文主要介绍第二种方式的下载。一般都是拿到接口返回的二进制文件后,前端转成blob,然后再转成URL,最后用隐藏a标签去下载此URL。
先上代码:
如下axios请求代码,注意要设置responseType为blob,以获取文件类型的响应数据。
export function downloadTools(query){
return request({
url: "/zip/download",
method:"get",
responseType:"blob",
params: query
})
}
前端接收代码,当请求操作失败的时候,接口会返回json形式的内容,所以需要FileReader的readAsText方法将其重新读取为字符形式的内容。当请求成功,返回二进制文件字符串的时候,使用 fileReader .readAsDataURL(blob) 或 URL.createObjectURL(blob) 创建URL对象,用隐藏的a标签去下载即可完成操作。
ps.一开始使用 fileReader .readAsDataURL(blob) 方法去下载80M的文件,会导致界面很卡顿,需要等待 fileReader.onload 方法加载完成,所以后面我换成了 URL.createObjectURL(blob) 响应很快,所以推荐使用后者。
const res = await downloadTools()
const that = this
if(res.type == 'application/json'){
const reader = new FileReader()
reader.readAsText(res,'utf-8')
reader.onload = function(){
const msg = JSON.parse(reader.result)
this.$message.warning(msg.message || "操作失败")
}
return
}
let blob = new Blob([res])
let a = document.createElement("a")
a.download = "文件.zip"
a.href = URL.createObjectURL(blob)
document.body.appendChild(a)
a.click()
//const fileReader = new FileReader()
//fileReader .readAsDataURL(blob)
//fileReader.onload = (e)=>{
// let a = document.createElement("a")
// a.download = "文件.zip"
// a.href = e.target.result
// document.body.appendChild(a)
// a.click()
//}
以下是cdn中对各个对象的描述:
Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。
Blob 表示的不一定是 JavaScript 原生格式的数据。File 接口基于 Blob,继承了 blob 的功能并将其扩展以支持用户系统上的文件。
一种从 Blob 中读取内容的方法是使用 FileReader。
通过创建一个新的、包含类型化数组中的数据的 Blob。然后调用 URL.createObjectURL() 方法,将 blob 转换为一个 URL。
JavaScript 类型化数组是一种类似数组的对象,并提供了一种用于在内存缓冲中访问原始二进制数据的机制。
引入类型化数组并非是为了取代 JavaScript 中数组的任何一种功能。相反,它为开发者提供了一个操作二进制数据的接口。这在操作与平台相关的特性时会很有用,例如:音频视频编辑和访问 WebSocket 原始数据等。JavaScript 类型化数组中的每一个元素都是以某种格式表示的原始二进制值,JavaScript 支持从 8 位整数到 64 位浮点数的多种二进制格式。
类型化数组拥有许多与数组相同的方法,语义也相似。但是,类型化数组并不是普通数组,因为在类型化数组上调用 Array.isArray() 会返回 false。此外,并不是所有可用于普通数组的方法都能被类型化数组所支持(如 push 和 pop)。
为了最大程度的灵活性和效率,JavaScript 将类型化数组的实现拆分为缓冲和视图两部分。缓冲是一种表示了数据块的对象,它没有格式可言,也没有提供访问其内容的机制。为了访问缓冲中的内存,你需要使用视图。视图提供了上下文——即数据类型、起始偏移量和元素数量。
统一资源定位器(URL)是指定在 Internet 上可以找到资源的位置的文本字符串。
在 HTTP 的上下文中,URL 被叫做”网络地址“或“链接”。你的浏览器在其地址栏显示 URL,例如 https://developer.mozilla.org
URL 也可用于文件传输(FTP) ,电子邮件(SMTP)和其他应用。
延申:
URI: Uniform Resource Identifier, 统一资源标识符。用来唯一标识资源,是一种语义上的抽象概念。
URL: Uniform Resource Locator, 统一资源定位符。用来定位唯一的资源, 必须提供足够的定位信息。
URI 是用来唯一标识资源, URL 提供资源的识别方法并用着各种方法定位资源。
由于互联网上每个文件都有唯一的URL, 所以URL是一种具体的URI, 可以说URL是URI的一种实现方式。
URI和URL都定义了是什么资源(唯一标识),但URL还定义了该如何访问或定位该资源。
文件上传包含原始的form表单上传等,不再过多赘述。稍后更新大文件的分片上传和断点续传。