《你不知道的 Blob》番外篇 上

简介: 《你不知道的 Blob》番外篇 上



最近原创文章回顾😊:

学习章节:《你不知道的 Blob》


原文对 Blob 的知识点介绍得非常完整清晰,本文通过四个问题来总结本文核心知识:

  1. Blob 是什么?
  2. Blob 怎么用?
  3. Blob 有哪些使用场景?
  4. Blob 与 ArrayBuffer 有何区别?


一、Blob 是什么?

Blob(Binary Large Object)表示二进制类型的大对象,通常是影像、声音或多媒体文件。MySql/Oracle数据库中,就有一种Blob类型,专门存放二进制数据。在 JavaScript 中 Blob 对象表示一个不可变、原始数据的类文件对象,它不一定非得是大量数据,也可以表示一个小型文件的内容。

另外,JavaScript 中的 File 接口是基于 Blob,继承 Blob 的功能并将其扩展使其支持用户系统上的文件。


二、Blob 怎么用?

Blob 由一个可选字符串 typeblobParts 组成,其中, type 通常为 MIME 类型。

MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,常见有:超文本标记语言文本 .html text/html 、PNG图像 .png image/png 、普通文本 .txt text/plain  等。

1. 构造函数

Blob 构造函数语法为:

const myBlob = new Blob(blobParts[, options])

入参:

  • blobParts:它是一个由 ArrayBuffer,ArrayBufferView,Blob,DOMString 等对象构成的数组。DOMStrings 会被编码为 UTF-8。
  • options:一个可选的对象,包含以下两个属性:
  • type :默认值为 "" ,表示将会被放入到 blob 中的数组内容的 MIME 类型。
  • endings :默认值为 "transparent",用于指定包含行结束符 \n 的字符串如何被写入。它是以下两个值中的一个:"native",代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 "transparent",代表会保持 blob 中保存的结束符不变。

出参:

返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成。

2. 属性和方法

2.1 属性介绍

Blob 对象拥有 2 个属性:

  • size :只读,表示 Blob 对象中所包含的数据大小(以字节为单位);
  • type :只读,值为字符串,表示该 Blob 对象所包含数据的 MIME 类型。若类型未知,则该属性值为空字符串。

2.2 方法介绍

  • slice([start[, end[, contentType]]]) :返回一个新的 Blob 对象,包含了源 Blob 对象中指定范围内的数据。
  • stream():返回一个能读取 Blob 内容的 ReadableStream
  • text():返回一个 Promise 对象且包含 Blob 所有内容的 UTF-8 格式的 USVString
  • arrayBuffer():返回一个 Promise 对象且包含 Blob 所有内容的二进制格式的 ArrayBuffer

注意:** Blob 对象是不可改变的**,但是可以进行分割,并创建出新的 Blob 对象,将它们混合到一个新的 Blob  中。类似于 JavaScript 字符串:我们无法更改字符串中的字符,但可以创建新的更正后的字符串。

3. 简单上手

3.1 示例1:从字符串创建 Blob

let myBlobParts = ['<html><h2>Hello Leo</h2></html>']; // 一个包含DOMString的数组
let myBlob = new Blob(myBlobParts, {type : 'text/html', endings: "transparent"}); // 得到 blob
console.log(myBlob.size + " bytes size");
// Output: 31 bytes size
console.log(myBlob.type + " is the type");
// Output: text/html is the type

3.2 示例2:从类型化数组和字符串创建 Blob

JavaScript类型化数组是一种类似数组的对象,并提供了一种用于 访问原始二进制数据的机制 。并且在类型数组上调用 Array.isArray() 会返回 false

详细可参考MDN《JavaScript 类型化数组》章节。

let hello = new Uint8Array([72, 101, 108, 108, 111]); // 二进制格式的 "hello"
let blob = new Blob([hello, ' ', 'leo'], {type: 'text/plain'});
// Output: "Hello leo"

3.3 示例3:组装新的 Blob

由于 Blob 对象是不可改变的,但我们可以进行分割,并组装成一个新的 Blob 对象:

let blob1 = new Blob(['<html><h2>Hello Leo</h2></html>'], 
   {type : 'text/html', endings: "transparent"});
let blob2 = new Blob(['<html><h2>Happy Boy!</h2></html>'], 
   {type : 'text/html', endings: "transparent"});
let slice1 = blob1.slice(16);
let slice2 = blob2.slice(0, 16);
await slice1.text();
// currtent slice1 value: "Leo</h2></html>"
await slice2.text();
// currtent slice2 value: "<html><h2>Happy "
let newBlob = new Blob([slice2, slice1], 
   {type : 'text/html', endings: "transparent"});
await newBlob.text();
// currtent newBlob value: "<html><h2>Happy Leo</h2></html>"

三、Blob 有哪些使用场景?

1. 图片本地预览

这里整理 2 种图片本地预览的方式:

  1. 使用 DataURL 方式;
  2. 使用 Blob URL/Object URL 方式;
<body>
    <h1>1.DataURL方式:</h1>
    <input type="file" accept="image/*" onchange="selectFileForDataURL(event)">
    <img id="output1">
    <h1>2.Blob方式:</h1>
    <input type="file" accept="image/*" onchange="selectFileForBlob(event)">
    <img id="output2">
    <script>
        // 1.DataURL方式:
        async function selectFileForDataURL() {
            const reader = new FileReader();
            reader.onload = function () {
                const output = document.querySelector("#output1")
                output.src = reader.result;
            }
            reader.readAsDataURL(event.target.files[0]);
        }
        //2.Blob方式:
        async function selectFileForBlob(){
            const reader = new FileReader();
            const output = document.querySelector("#output2");
            const imgUrl = window.URL.createObjectURL(event.target.files[0]);
            output.src = imgUrl;
            reader.onload = function(event){
                window.URL.revokeObjectURL(imgUrl);
            }
        }
    </script>
</body>

上面主要介绍 Blob URLData URL 两种方式实现图片本地预览,这两个类型的区别在**《五、拓展》**中介绍。

2. 图片本地预览 + 分片上传

实现本地预览:

input 获取到的 file 对象,通过实例化 FileReader ,赋值给变量 reader ,调用readerreadAsDataURL 方法,将 file 对象转换为  dataURL ,然后监听 readeronload 属性,获取到读取结果 result ,然后设置为图片的 src 值。


实现分片上传:

由于 File 是特殊类型的 Blob,可用于任意 Blob 类型的上下文,所以针对大文件传输,我们可以使用 slice 方法进行文件切割,分片上传。

<body>
    <input type="file" accept="image/*" onchange="selectFile(event)">
    <button onclick="upload()">上传</button>
    <img id="output">
    <script>
        const chunkSize = 10000;
        const url = "https://httpbin.org/post";
        async function selectFile(){
           // 本地预览
            const reader = new FileReader();
            reader.onload = function(){
                const output = document.querySelector("#output")
                output.src = reader.result;
            }
            reader.readAsDataURL(event.target.files[0]);
           // 分片上传
            await upload(event.target.files[0]);
        }
        async function upload(files){
            const file = files;
            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) =>{
                    console.log(res)
                    res.text();
                });
            }
        }
    </script>
</body>

3. 图片本地预览 + 分片上传 + 暂停 + 续传

<body>
    <input type="file" accept="image/*" onchange="selectFile(event)">
    <button onclick="upload()">上传</button>
    <button onclick="pause()">暂停</button>
    <button onclick="continues()">继续</button>
    <img id="output" src="" alt="">
    <script>
        const chunkSize = 30000;
        let start = 0, curFile, isPause = false;
        const url = "https://httpbin.org/post";
        async function selectFile(){
            const reader = new FileReader();
            reader.onload = function(){
                const output = document.querySelector("#output")
                output.src = reader.result;
            }
            reader.readAsDataURL(event.target.files[0]);
            curFile = event.target.files[0];
        }
        async function upload(){
            const file = curFile;
            for(start; start < file.size; start += chunkSize){
                if(isPause) return;
                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()
                    }
                );
                if(chunk.size < chunkSize){
                    uploadSuccess();
                    return;
                }
            }
        }
        function pause(){
            isPause = true;
        }
        function continues(){
            isPause = false;
            upload();
        }
        function uploadSuccess(){
            isPause = false;
            start = 0;
        }
    </script>
</body>


目录
相关文章
|
10月前
|
JavaScript 前端开发 应用服务中间件
【前端项目笔记】原生js上传文件及文件转换成base64、blob类型
项目中经常会用到上传图片上传视频等功能,由于后端nginx限制,经常要进行文件转化才能上传,大文件可能还要进行切片上传处理。
482 1
|
2天前
Halcon 学习笔记二:简单blob分析
Halcon 学习笔记二:简单blob分析
44 0
|
6月前
|
JavaScript 前端开发
超适合0基础js对象笔记(10.)
超适合0基础js对象笔记(10.)
70 1
|
6月前
|
C++
《C++避坑神器·十四》项目路径获取及WCHAR 和char* 的相互转换
《C++避坑神器·十四》项目路径获取及WCHAR 和char* 的相互转换
45 0
|
前端开发
前端学习案例3-blob对象实现图片预览3
前端学习案例3-blob对象实现图片预览3
92 0
前端学习案例3-blob对象实现图片预览3
|
前端开发
前端学习案例2-blob对象实现文件的下载和图片预览2
前端学习案例2-blob对象实现文件的下载和图片预览2
89 0
前端学习案例2-blob对象实现文件的下载和图片预览2
|
前端开发
前端学习案例1-blob对象实现文件的下载和图片预览1
前端学习案例1-blob对象实现文件的下载和图片预览1
119 0
前端学习案例1-blob对象实现文件的下载和图片预览1
|
开发工具 文件存储 对象存储
阿里云图片上传返回地址有blob格式问题处理实录
阿里云OSS上传图片功能很多人可能对实现过,正常情况下会返回https开头的图片地址.
阿里云图片上传返回地址有blob格式问题处理实录
|
存储 前端开发 JavaScript
《你不知道的 Blob》番外篇 下
《你不知道的 Blob》番外篇 下
243 0
|
JSON JavaScript 前端开发
【前端知乎系列】ArrayBuffer 与 Blob对象
【前端知乎系列】ArrayBuffer 与 Blob对象
321 0