一.文件下载
1.简要:文件下载分为两种情况。
(1)第一种是后台放在服务器上面,然后前端直接访问就可以下载,此种前端不需要做额外的处理,可以用 type为download的a标签直接访问下载,也可以用window.open或location.href=""这种方式直接访问即可下载。
(2)第二种是前端访问接口,然后后端返回二进制文件。前端完成解析后下载。本文主要介绍第二种方式的下载。一般都是拿到接口返回的二进制文件后,前端转成blob,然后再转成URL,最后用隐藏a标签去下载此URL。
2.实际运用
先上代码:
如下axios请求代码,注意要设置responseType为blob,以获取文件类型的响应数据。
javascript
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) 响应很快,所以推荐使用后者。
javascript
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()
//}
3.拓展
以下是cdn中对各个对象的描述:
Blob
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
统一资源定位器(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表单上传等,不再过多赘述。稍后更新大文件的分片上传和断点续传。