Blob:前端的一个专门用于支持文件操作的二进制对象
ArrayBuffer:前端的一个通用的二进制缓冲区,类似数组,但在 API 和特性上却有诸多不同
Buffer:Node.js 提供的一个二进制缓冲区,常用来处理 I/O 操作
Blob
Blob 是表示二进制类型的大对象,用来支持文件操作的。简单的说:在 JS 中,有两个构造函数 File 和 Blob ,而 File 继承了所有 Blob 的属性。所以在我们看来, File 对象可以看作一种特殊的 Blob 对象。
Blob 对象有两个属性: size 和 type 。其中 size 属性用于表示数据的大小(以字节为单位), type 是 MIME 类型的字符串。
常见的 MIME 类型有:超文本标记语言文本 .html text/html 、 PNG 图像 .png image/png 、普通文本 .txt text/plain 等。
如何获取 File 对象: File 对象是一种特殊的 Blob 对象,那么它自然就可以直接调用 Blob 对象的方法。让我们看一看 Blob 具体有哪些方法,以及能够用它们实现哪些功能。
构建
var aBlob = new Blob(blobParts, options);
- blobParts:一个由 ArrayBuffer ,ArrayBufferView ,Blob ,DOMString 等对象构成的数组。
- options:一个可选的对象,包含以下两个属性:
- type :默认值为
""
,它代表了将会被放入到 blob 中的数组内容的 MIME 类型。 - endings:默认值为
"transparent"
,用于置顶包含行结束符\n
的字符串如何被写入。"native"
代表行结束符会被更改为适合宿主操作系统文件系统的换行符,"transparent"
代表会保持 blob 中保存的结束符不变。
- type :默认值为
实战
通过 window.URL.createObjectURL 方法可以把一个 blob 转化为一个 Blob URL ,并且用作文件下载或者图片显示的链接。
Blob URL 所实现的下载或者显示等功能,仅仅可以在单个浏览器内部进行。而不能在服务器上进行存储,亦或者说它没有在服务器端存储的意义。
Blob 下载文件
<a id="h">点此进行下载</a>
<script>
var blob = new Blob(["Hello World"])
var url = window.URL.createObjectURL(blob)
var a = document.getElementById('h')
a.download = "helloworld.txt"
a.href = url
</script>
Blob 图片本地显示
<input type="file" id="f" />
<img id="img" style="width: 200px; height: 200px;" />
<script>
document.getElementById("f").addEventListener("change", function(e) {
const file = this.files[0];
const img = document.getElementById("img")
const url = window.URL.createObjectURL(file)
img.src = url;
img.onload = function() {
// 释放一个之前通过调用 URL.createObjectURL 创建的 URL 对象
window.URL.revokeObjectURL(url)
}
})
</script>
Blob 是针对文件的,或者可以说它就是一个文件对象,欠缺对二进制数据的细节操作能力,比如如果要具体修改某一部分的二进制数据, Blob 显然就不够用了。
切割大文件上传
使用 slice 方法,接受三个参数,起始偏移量,结束偏移量,还有可选的 mime 类型。
当要上传大文件的时候,可以将大文件分割分段,然后各自上传。
const file = new File(["a".repeat(1000000)], "test.txt");
const chunkSize = 40000;
const url = "https://httpbin.org/post";
async function chunkedUpload() {
for (let start = 0; start < file.size; start += chunkSize) {
const chunk = file.slice(start, start + chunkSize + 1);
const fd = new FormData();
fd.append("data", chunk);
await fetch(url, { method: "post", body: fd }).then((res) =>
res.text()
);
}
}
隐藏真实视频源
服务端使用 nodejs,koa 框架,这里的操作很简单,就是用 fs.readFileSync
直接打开视频文件,得到的 data 结果是二进制的数据,直接作为结果返回。
const Koa = require('koa')
const Router = require('koa-router')
const buffer = require('buffer');
const app = new Koa()
const router = new Router()
const fs = require('fs')
const video = async (ctx, next) => {
try {
// open 一个放在服务器的视频
let data = fs.readFileSync('XXX.XXX.XXX/simple.mp4')
ctx.response.body = data
} catch (e) {
return Promise.reject({
status: 500,
message: '视频传输错误'
})
}
next()
}
router.get('/video', video)
app.use(router.routes()).use(router.allowedMethods())
app.listen(3001)
接下来看前端代码,这里使用的最原生的 XMLHttpRequest
对象语法,这里最重要的一点是要设置 responseType 为 blob ,这样接收到 response 直接就是一个 blob 对象供我们使用。这个 responseType 属性不属于 http 头部信息,而是 ajax 请求中 XHR 对象的属性(默认为””也就是 text
类型,而在一些封装 XHR 的框架中,一般把默认值设为 json
)。
let xhr = new XMLHttpRequest()
xhr.open('GET', 'http://localhost:3001/video', true)
xhr.responseType = 'blob'
xhr.onload = function(e) {
if (this.status === 200) {
// 获取blob对象
let blob = this.response
console.log(blob)
// 获取blob对象地址,并把值赋给容器
$("#sound").attr("src", URL.createObjectURL(blob));
}
}
xhr.send()
这样就可以得到以 blob:
开头的临时 url 地址,而且在向服务端请求时页隐藏了真实的视频地址。
Blob URL
Blob URL 是 blob 协议的 URL ,它的格式如下:
blob:http://xxx
Blob URL 可以通过 URL.createObjectURL(blob) 创建。在绝大部分场景下,我们可以像使用 HTTP 协议的 URL 一样,使用 Blob URL 。常见的场景有:作为文件的下载地址和作文图片资源地址。
Blob URL 和 Data URL 的区别
- Blob URL 的长度一般比较短,但 Data URL 因为直接存储图片 base64 编码后的数据,往往很长。当显示大图片时,使用 Blob URL 能获取更好的可能性。
Blob URL 可以方便的使用 XMLHttpRequest 获取源数据,对于 Data URL ,并不是所有浏览器都支持通过 XMLHttpRequest 获取源数据的。例如:
var blobUrl = URL.createObjectURL(new Blob(["Test"], {type: "text/plain"}));
var x = new XMLHttpRequest();
x.onload = function() {
alert(x.responseText); // Test
};
x.open("get", blobUrl);
x.send();
Blob URL 只能在当前应用内部使用。
参考链接: