Blob
Blob 全称为 binary large object: 二进制大对象,blob 对象本质上是 js 中的一个对象,里面可以存储大量的二进制编码格式的数据
↓ Blob 对象是不可修改的,r如果想修改 Blob 对象可以通过先转化成 FileReader、ArrayBuffer 等类型对象并进行修改,修改后再将该修改的数据生成一个新的 Blob 对象
Blob 基本创建:
-
/** + blobParts: 一个可迭代对象 - 通常是 array,包含 ArrayBuffer、TypedArray、DataView、Blob、字符串或者任意这些元素的混合,这些元素将会被放入 Blob 中 + options: - type: 默认值为 "",表示将会被放入到 blob 中的数组内容的 MIME 类型 → 如: text/plain、text/html、application/json 等 - endings: 取值 "transparent"/"native",如果内容是文本时,对 "\n" 换行符的处理模式 → 了解即可: 非标准参数,使用前先检查浏览器是否兼容 - transparent: 会将换行符复制到 blob 中而不会改变它们 → 不做操作 - native: 将换行符转换为主机系统的本地约定 → 解析为换行 */ const blob = new Blob(blobParts, options)
-
// -- 示例 const blob = new Blob(["deng-cl"], { type: "text/plain" }) console.log(blob); // log: Blob {size: 7, type: 'text/plain'}
Blob 实例属性:
- size:
属性返回 Blob 或 File 的字节大小
- type:
属性返回文件的 MIME 类型
注意: 此属性不会读取文件的字节流来确定其 MIME 类型,通常只会对常见的文件类型有效,不常见的文件扩展名会返回空字符串
另外,客户端配置也有可能导致常见类型出现意外值(例如 Windows 注册表)
所以,开发者不应该仅依赖此属性作为验证方案
Blob 实例方法:
-
slice:
方法创建并返回一个新的
Blob对象,该对象包含调用它的 blob 的子集中的数据
即对二进制内容进行切片,返回一个新的 blob 对象,内容为对应切片区域中的二进制数据
-
/** slice 实例方法参数 ↓ * + start : 开始截取的位置 * + end: 截取结束的位置 * + contentType: 截取出来的 blob 的类型,如果省略 type,则默认为 blob 的原始值 */ const blob2 = blob.slice(0, 4, "text/plain") console.log(blob2) // log: Blob {size: 4, type: 'text/plain'} // -- blob2 中的内容就为上面 blob 中的 "deng",读取 Blob 对象中的内容需要 FileReader 实例来进行读取(后续示例)
-
-
text:
方法返回一个 Promise,其会兑现一个包含 blob 内容的 UTF-8 的字符串
即: 其兑现的内容为 blob 中内容的 UTF-8 格式的字符串(可以理解为作为文本返回)
-
// -- 示例 → 通过 text 方法兑现的 blob 内容,获取上面 blob 中的内容(utf-8 字符串) blob.text().then(res => console.log(res)) // log: deng-cl
-
-
arrayBuffer:
方法返回一个 Promise,其会兑现一个包含 blob 二进制数据内容的 ArrayBuffer 对象
具体 ArrayBuffer 的使用,后续学习
-
stream:
方法返回一个 ReadableStream 可读流对象,可通过读取该可读流将其返回包含中 blob 中的数据
具体 ReadableStream 的使用,后续学习
File
File 对象继承至 Blob,是一个特殊的 Blob: 在 JavaScript 中主要有如下两种方式获取 File
因为该 File 继承至 Bolb,所以 Blob 中的有的属性与方法,在 File 对象中也存在
-
1. 用户通过 input 标签元素选择文件后返回的 Filelist 对象,在对象中检索对应选择的文件
-
<input type="file" id="file"> <!-- input 文件选择表单 -->
-
const inputEl = document.querySelector("#file") // -- 获取上面 input 表单的 DOM 元素 inputEl.onchange = e => { // -- 监听 input 的改变 // -- 通过 input DOM元素中的 files 属性获取所选择的文件信息 Filelist,该 Filelist 是一个可迭代对象(类数组) const files = e.target.files // -- 里面包含选择的所有文件的信息对象 File console.log(files) }
-
-
2. 文件拖放操作生成的 DataTransfer 对象
→ 从桌面等将文件拖放到指定位置
-
<div class="drop-area"></div> <!-- 拖放容器 -->
-
.drop-area { /* 容器样式: 使其可以更好的演示 */ width: 300px; height: 300px; border: 1px solid #ccc; margin-top: 20px; }
-
const dropAreaEl = document.querySelector(".drop-area") // -- 获取拖放容器 DOM 元素 dropAreaEl.ondragover = e => { // -- 监听拖放容器中的拖放事件(进入拖放容器) e.preventDefault() // -- 阻止默认行为,否则会触发默认事件,在浏览器中打开该文件 → 对应后续对文件操作部分将不会执行到 } dropAreaEl.ondrop = e => { // -- 监听拖放容器中的拖放事件(在拖放容器中释放) e.preventDefault() const files = e.dataTransfer.files // -- 获取拖放容器中的文件信息 Filelist,该 Filelist 是一个可迭代对象(类数组) console.log(files) }
-
总结拖放选择文件流程:
-
1. 定义拖放容器元素(拖放区域) 2. 通过监听 dragover 拖拽事件与 drop 放下事件,来获取对应的文件信息 3.🔺注意: ↑该两个事件都需要阻止对应的浏览器默认行为,因为该两个事件的默认行为会在浏览器新窗口中打开对应的文件(如果不进行阻止,则不会执行对应事件监听中的回调,导致无法获取对应的信息) 4. 在拖拽事件中,可以通过对应容器 DOM 中的 dataTransfer 对象中的 files 属性获取对应的 Filelist 迭代对象(类数组)
-
-
File 示实例属性:
-
lastModified:
属性返回返回文件上次修改的日期的 "Unix 时间戳"(1970-1-1 00:00:00 UTC 至今的毫秒数)
没有已知最后修改日期的文件返回当前日期
-
lastModifiedDate(弃用):
返回文件最后一次修改的时间,已弃用,请尽量使用上面的 lastModified 属性获取修改时间
-
name:
属性返回对应文件的名称
File 实例方法: 暂无实例方法
因为 File 继承至 Blob,所以原型链中也存在 Blob 的实例方法
FileReader
FileReader: 该 API 允许 web 程序异步读取用户计算机中的文件(或原始数据缓存区)的内容
使用 File 或 Blob 对象指定要读取的文件或数据 → 即读取 File/Blob 中的内容
创建 FileReader 实例:
-
const fileReader = new FileReader() // -- 创建一个 FileReader 实例对象
实例属性:
-
error:
属性返回读取文件时返回的错误
-
readyState:
属性返回当前读取操作的状态 EMPTY | LOADING | DONE
-
0 : Reader已创建,尚未调用任何读取操作 → EMPTY 1 : 已调用读取方法,正在读取 File 或 Blob,尚未发生错误 → LOADING 2 : 读取操作完成 → DONE
-
-
result:
属性返回文件的内容(仅在读取完成后有效)
具体数据格式取决于使用哪种实例方法来启动读取操作(字符串或 ArrayBuffer 对象),如果读取未完成或失败时为 null
实例方法: → 数据读取
-
readAsArrayBuffer:
用户读取 Blob 或 FIle 中的内容,当读取完成后 readyState 属性变为 DONE 状态,并触发 load 事件,此时 result 属性就包含一个表示文件数据的 arrayBuffer 对象
→ 读取为 arrayBuffer 格式 : 具体 ArrayBuffer 的使用,后续学习
-
readAsDataURL:
将内容读取为 Base64 编码字符串
→ base64
-
<input type="file" id="file">
-
const inputEl = document.querySelector("#file") inputEl.onchange = e => { const files = e.target.files const fileReader = new FileReader() // -- 1. 创建一个 FileReader 实例对象 fileReader.readAsDataURL(files[0]) // -- 2. 读取文件(base64) fileReader.onload = e => { // -- 3. 监听文件读取完成 console.log(e.target.result, " 或 ", fileReader.result) // -- 4. 读取完成后,通过 result 属性获取文件内容 } }
-
-
readAsText:
将内容读取为文本字符串
→ 文本
-
const blob = new Blob(['deng-cl'], { type: 'text/plain' }); const blobSlice = blob.slice(0, 4)
-
const fileReader = new FileReader() // -- 1. 创建 FileReader 实例对象 fileReader.readAsText(blobSlice) // -- 2. 读取 Blob 中的内容 fileReader.onload = e => { // -- 3. 监听文件读取完成 console.log(e.target.result) // log: deng }
-
-
abort:
用于中止读取操作
readyState 也为 DONE 完成
-
fileReader.abort() // -- 中止读取: 在读取完成前进行中止读取操作的,不会进入对应的 load 事件中(虽然 readyState 也为 DONE) fileReader.onload = e => { console.log(e.target.result) }
-
实例事件:
-
loadStart:
读取操作开始时触发
-
progress:
读取过程中定期触发
-
load:
读取成功时触发
-
loadend:
读取完成时触发(无论是否成功)
-
error:
读取失败时触发
例如: 因为文件未找到或不可读 → 导致读取失败时触发
-
abort:
读取中止时触发
调用 abort 方法