Blob:
是浏览器环境上提供的一种大对象,通常是影像、声音或多媒体文件等原始数据的二进制对象,它和 ArrayBuffer 没有必然联系,但是又可以互相转化,Blob用于操作二进制文件,而 ArrayBuffer 用于操作内存。
详见Blob

const blob = new Blob( array, options );
  • 第一个参数 array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings会被编码为UTF-8。

var htmlFragment = ['<a id="a"><b id="b">hey!</b></a>'];
var myBlob = new Blob(htmlFragment, {type : 'text/html'});
  • BlobURL(ObjectURL)是一种伪协议,只能由浏览器在内部生成,我们知道script/img/video/iframe等标签的src属性和background的url可以通过url和base64来显示,我们同样可以把blob或者file转换为url生成BlobURL来展示图像,BlobURL允许Blob和File对象用作图像,下载二进制数据链接等的URL源

    • BlobURL并不代表数据本身,数据存储在浏览器中,BlobUrl只是访问它的key。数据会一直有效,直到关闭浏览器或者手动清除。 因此即使将BlobUrl传递给服务器等也无法访问数据
var droptarget = document.getElementById('droptarget');droptarget.ondrop = function (e) {var files = e.dataTransfer.files;for (var i = 0; i < files.length; i++) {var type = files[i].type;if (type.substring(0,6) !== 'image/')continue;var img = document.createElement('img');img.src = URL.createObjectURL(files[i]);img.onload = function () {this.width = 100;document.body.appendChild(this);URL.revokeObjectURL(this.src);}}
}
  • 下载文件
<body><button onclick="download()">download.txt</button><script>const getObjectURL = (file) => {let url;if (window.createObjectURL) {url = window.createObjectURL(file);} else if (window.URL) {url = window.URL.createObjectURL(file);} else if (window.webkitURL) {url = window.webkitURL.createObjectURL(file);}return url;};function download() {const fileName = 'download.txt';const myBlob = new Blob(['johnYu'], { type: 'text/plain' });downloadFun(fileName, myBlob);}function downloadFun(fileName, blob) {const link = document.createElement('a');link.href = getObjectURL(blob);link.download = fileName;link.click();link.remove();URL.revokeObjectURL(link.href);}</script></body>
  • 文件选择器返回一个 FileList 对象,该对象是一个类似数组的成员,每个成员都是一个 File 实例对象。File 实例对象是一个特殊的 Blob 实例,增加了name和lastModifiedDate属性
// HTML 代码如下
// <input type="file" accept="image/*" multiple οnchange="fileinfo(this.files)"/>function fileinfo(files) {for (var i = 0; i < files.length; i++) {var f = files[i];console.log(f.name, // 文件名,不含路径f.size, // 文件大小,Blob 实例属性f.type, // 文件类型,Blob 实例属性f.lastModifiedDate // 文件的最后修改时间);}
}
  • 服务器返回二进制数据
function getBlob(url, callback) {var xhr = new XMLHttpRequest();xhr.open('GET', url);xhr.responseType = 'blob';xhr.onload = function () {callback(xhr.response);}xhr.send(null);
}
  • 生成 URL
var droptarget = document.getElementById('droptarget');droptarget.ondrop = function (e) {var files = e.dataTransfer.files;for (var i = 0; i < files.length; i++) {var type = files[i].type;if (type.substring(0,6) !== 'image/')continue;var img = document.createElement('img');img.src = URL.createObjectURL(files[i]);img.onload = function () {this.width = 100;document.body.appendChild(this);URL.revokeObjectURL(this.src);}}
}
  • 分片上传
<!-- html部分 -->
<input type="file" id='f' />
<!-- js部分 -->
<script>
function upload(blob) {var xhr = new XMLHttpRequest();xhr.open('POST', '/ajax', true);xhr.setRequestHeader('Content-Type', 'text/plain')xhr.send(blob);
}document.getElementById('f').addEventListener('change', function (e) {var blob = this.files[0];const CHUNK_SIZE = 20; .const SIZE = blob.size;var start = 0;var end = CHUNK_SIZE;while (start < SIZE) {upload(blob.slice(start, end));start = end;end = start + CHUNK_SIZE;}
}, false);
</script>
  • FileReader操作Blob对象
var fileReader = new FileReader();fileReader.readAsText(blob):返回文本,需要指定文本编码,默认为 UTF-8。
fileReader.readAsArrayBuffer(blob):返回 ArrayBuffer 对象。
fileReader.readAsDataURL(blob):返回 Data URL。
fileReader.readAsBinaryString(blob):返回原始的二进制字符串。

DataUrl:
允许内容的创建者将较小的文件嵌入到文档中。由于可以将其用作URL的替代,因此DataURL和BlobUrl一样可以在script/img/video/iframe等标签的src属性和background的url中使用,用法与BlobUrl基本一致

data:[<mediatype>][;base64],datadata:前缀mediatype表明数据类型,是一个MIME类型字符串,如image/jpeg表示一个JPEG图片文件。如果省略,默认值为text/plain;charset=US-ASCII。base64:标志位(如果是文本,则可选)data:数据本身


atob(): 负责解码已经使用base64编码了的字符串。
btoa(): 将二进制字符串转为base64编码的ASCII字符串。

btoa('<xml>foo</xml>') // "PHhtbD5mb288L3htbD4="
atob('PHhtbD5mb288L3htbD4=') // "<xml>foo</xml>"
  • 文件下载
  <script>const createDownload = (fileName, content) => {const blob = new Blob([content]);const reader = new FileReader();const link = document.createElement('a');link.innerHTML = fileName;link.download = fileName;reader.onload = () => {link.href = reader.result;document.getElementsByTagName('body')[0].appendChild(link);};reader.readAsDataURL(blob);};createDownload('download.txt', 'johnYu');</script>
  • 与BlobURL的区别

    • DataUrl是直接编码的数据本身。关闭浏览器后仍然可以在地址栏访问,DataUrl由于数据本身由URL表示,因此可以将其保存在Cookie中传递给服务器

    • BlobUrl的长度一般比较短,但DataUrl因为直接存储图片base64编码后的数据,往往很长(Base64编码的数据体积通常会比二进制格式的图片体积大1/3。),因此当显式大图片时,使用BlobUrl能获取更好的可能性,速度和内存比DataUrl更有效

    • DataUrl不会被浏览器缓存,但是小部分会通过css缓存,如避免了让图片独自产生一次HTTP请求,不会每次使用时都加载一次

    • BlobUrl始终是唯一字符串,即时你每次传递相同的Blob,每次也会生成不同的BlobUrl;DataUrl值跟随blob变化;

ArrayBuffer:
是最基础的二进制对象,是对固定长度的连续内存空间的引用,存了一堆字节,也无法直接操作它。

//创建一个长度为8的ArrayBuffer,此时开辟一个固定8个字节的缓冲区也就是64位
var buffer = new ArrayBuffer(8);//返回大小
buffer.byteLength    //8//复制一部分内存,slice用法和js相似
var buf2 = buf1.slice(0);  

如果我们想操作这段内存空间怎么办呢?这时候就需要一个称之为视图的家伙

  • Uint8Array,Uint16Array,Uint32Array等这几个东西就是视图。你可以把它理解成 ArrayBuffer 的翻译器,只不过他们的翻译方式有点不同:

    • Uint8Array 将 ArrayBuffer 中的8位,及每个字节视为一个单位。每个单位是 0 到 255 之间的数字。之所以是255,是因为每个单位最多是 8 位,即 2^8 次方。
    • Uint16Array 将 ArrayBuffer 中的16位,及每 2 个字节视为一个单位,即2^16。每个单位是 0 到 65535 之间的整数。原理同上。
    • Uint32Array 将 ArrayBuffer 中的32位,及每 4 个字节视为一个单位,即2^32。每个单位是 0 到 4294967295 之间的整数。原理同上。
// 我们可以通过 BYTES_PER_ELEMENT 静态属性来得之视图单位的大小
const buf8 = new Uint8Array();
const buf16 = new Uint16Array();
const buf32 = new Uint32Array();
console.log(buf8.BYTES_PER_ELEMENT); // 1
console.log(buf16.BYTES_PER_ELEMENT); // 2
console.log(buf32.BYTES_PER_ELEMENT); // 4
  • TypedArray就是上面提到的 Uint8Array 等的统称。他们都是 TypedArray (类型数组)的一种形式罢了,并不存在 TypedArray 这个构造函数。这只是一个统称
  • 每个位首代表正负符号。故而 Int8Array 每个元素大小范围为-128~127。



  • 换算为10进制,Uint16Array中每个元素大小范围为 0 ~ 2^16 也就是 0 ~ 65536 。
// 创建8个字节长度的缓存冲
const buffer = new ArrayBuffer(8);const uint8Array = new Uint8Array(buffer);// log: [0, 0, 0, 0,0, 0, 0, 0]
console.log(uint8Array);// 将buffer转化为Uint16Array
// Uint8Array中每一个元素表示两个字节(16位)
const uint16Array = new Uint16Array(buffer);// log: Uint16Array(4) [ 0, 0, 0, 0 ]
console.log(uint16Array);// 64位 8字节 -> 4个元素(log:4)
console.log(uint16Array.length);
//
  • DataView是一种底层的,更灵活的读取 ArrayBuffer 的视图。 从上文中我们知道诸如 Unit8Array 之类的 “翻译器” (视图)可以用来翻译 ArrayBuffer,但有的时候我们并不想固化 “翻译” 类型,比如我有的时候想用 8 翻译,有的时候想用 16 翻译。DataView 就是一种更灵活的视图,相较与 TypedArray 每个元素中固定的字节大小,我们可以通过 DataView 来自由的操作 ArrayBuffer
new DataView(buffer [, byteOffset [, byteLength]])
  • 第一个参数 buffer 为必填,它支持传入一个 ArrayBuffer 表示 DataView 中的源数据。
  • 第二个参数 byteOffset 选填,它表示创建 DataView 时开头从 buffer 的哪个字节开始,可以作为启始偏移量。未指定时,默认从第一个字节开始。
  • 第三个参数 btyeLength 选填,它表示创建该 DataView 时的长度,当不传递默认时表示匹配 buffer 的长度。
// 创建8个字节长度的缓存冲
const buffer = new ArrayBuffer(8);// 根据传入的buffer 从第一个字节开始,并且字节长度为匹配buffer的长度
const dataView = new DataView(buffer);// 将DataView中偏移量为0个字节的字节,也就是第一个字节设置为十进制的1
dataView.setUint8(0, 1);
// 将DataView中偏移量为1个字节的字节,也就是第二个字节设置为十进制的2
dataView.setUint8(1, 2);// 从dataView中偏移第0个字节,也就是第一个字节,获取8位
// log: 1
dataView.getUint8(0);// 从dataView中偏移第一个字节获取八位,也就是获取第二个字节的值
// log: 2
dataView.getUint8(1);// 偏移量为0个字节,获取后续16位大小(也就是获取前两个字节大小)
// log: 258
dataView.getUint16(0);// 偏移量为2个字节,设置后16位大小为256(也就是设置第三个字节和第四个字节大小和为256)
dataView.setUint16(2, 256);// 偏移量为2个字节,获取后16位大小
// log: 256
dataView.getUint16(2);
  • 分别将第一个字节(8位)的值变为 1 和将第二个字节变为 10 进制的 2。


  • 服务器返回二进制数据
et xhr = new XMLHttpRequest();
xhr.open('GET', someUrl);
xhr.responseType = 'arraybuffer';xhr.onload = function () {let arrayBuffer = xhr.response;// ···
};xhr.send();

Buffer:
即缓存,去存储这些暂时用不上的数据(传的比 cpu 处理快,这个位置就存着提前到达的数据;比 cpu 处理慢,这个位置就存够一批足够能用的数据再给 cpu)这个区域就称之为缓存区(Buffer),一般是内存空间作为缓存空间。

node中的Buffer:
是 Uint8Array 类的子类,除了 Buffer 对象之外,Stream 和 Readline 也是比较常用的 node 内置二进制处理模块,使用这种二进制处理模块比常规的数组更快捷

// Node端(Koa)
const app = new Koa();
app.use(async (ctx, next) => {if (ctx.path === '/ajax') {const chunks = [];const req = ctx.req;req.on('data', buf => {chunks.push(buf);})req.on('end', () => {let buffer = Buffer.concat(chunks);console.log(buffer.toString())})}
});
app.listen(3000)// 前端
const xhr = new XMLHttpRequest();
xhr.open("POST", "ajax", true);
xhr.setRequestHeader('Content-Type', 'text/plain')
xhr.send("asdasdsadfsdfsadasdas");运行结果
// 创建10个字节大小的空buffer
const buf1 = Buffer.alloc(10);// 根据内容直接创建buffer
const buf2 = Buffer.from("hello buffer")//将数据进行Unicode编码并展示
buf2.toJSON()//buffer的大小
buf2.length   //12//写入数据到buffer
buf1.write("Buffer really rocks!")//解码buffer
buf1.toString()    // 'Buffer rea' buf1只有十个字节大小

关系及转换

  • 字符串 → Uint8Array
    var str = 'ab';console.log(Uint8Array.from(str.split(''), (e) => e.charCodeAt(0))); // Uint8Array(2) [97, 98]
  • Uint8Array → 字符串
    var u8 = Uint8Array.of(97, 98);console.log(Array.from(u8, (e) => String.fromCharCode(e)).join('')); // ab
  • 字符串 → DataUrl
    var str = 'ab';console.log('data:application/octet-stream;base64,' + btoa(str)); // data:application/octet-stream;base64,YWI=
  • DataUrl -> 字符串
    var data = 'data:application/octet-stream;base64,YWI=';console.log(atob(data.split(',')[1])); // ab
  • Uint8Array -> ArrayBuffer
    var u8 = Uint8Array.of(1, 2);console.log(u8.buffer); // ArrayBuffer(2) {}
  • ArrayBuffer -> Uint8Array
    var buffer = new ArrayBuffer(2);console.log(new Uint8Array(buffer)); // Uint8Array(2) [0, 0]
  • ArrayBuffer -> DataView
    var buffer = new ArrayBuffer(2);var dataView = new DataView(buffer, 0); // DataView(2) {}
  • DataView -> ArrayBuffer
    console.log(dataView.buffer); // ArrayBuffer(2) {}
  • ArrayBuffer → Blob
    var buffer = new ArrayBuffer(32);var blob = new Blob([buffer]);  // Blob {size: 32, type: ""}
  • UintXXArray → Blob
    var u8 = Uint8Array.of(97, 32, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33);var blob = new Blob([u8]);
  • 字符串 → Blob
    var blob = new Blob(['Hello World!'], {type: 'text/plain'}); // Blob {size: 12, type: "text/plain"}
  • DataUrl -> blob
    var data = 'data:application/octet-stream;base64,YWI=';function dataURLtoBlob(dataurl) {var arr = dataurl.split(','),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new Blob([u8arr], { type: mime });}console.log(dataURLtoBlob(data)); // Blob {size: 2, type: "application/octet-stream"}

js Blob、ArrayBuffer(Uint8Array、TypedArray、DataView)、Buffer、DataUrl相关推荐

  1. javascript(js)语法 将blob转arrayBuffer、arrayBuffer转Uint8Array、Uint8Array转String的方法

    文章目录 javascript(js)语法 将blob转arrayBuffer.arrayBuffer转Uint8Array.Uint8Array转String的方法 1. blob转arrayBuf ...

  2. html5 文件转byte[],JS 文件base64、File、Blob、ArrayBuffer互转

    二进制互转 1. file对象转base64let reader = new FileReader(); reader.readAsDataURL(file[0]) console.log(reade ...

  3. 理解DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型

    FormData 对象的使用地址:https://developer.mozilla.org/zh-CN/docs/Web/API/FormData/Using_FormData_Objects 一. ...

  4. DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型

    一.XMLHttpRequest 2.0的家臣们 我大学那会儿,一个称为Ajax的东西对前端行业造成了深远影响,不仅是JS语言,而包括前端地位.职位兴起以及工作分工等.抛开IE6浏览器不谈,其他浏览器 ...

  5. java filereader blob_二进制学习——Blob,ArrayBuffer、File、FileReader和FormData的区别

    前言: Blob.ArrayBuffer.File.fileReader.formData这些名词总是经常看到,知道一点又好像不知道,像是同一个东西好像又不是,总是模模糊糊,最近终于下决心要弄清楚. ...

  6. Buffer、ArrayBuffer、DataView互转(node.js)

    1.Buffer转ArrayBuffer // 实例一 const buf = Buffer.from("this is a test"); console.log(buf); c ...

  7. vuejs项目前端纯js在线下载网页内容保存为自定义格式的word文件、另存为word文件

    所有前端导入导出方法集合: 前端必备技能知识:JS导出Blob流文件为Excel表格.Vue.js使用Blob的方式实现excel表格的下载(流文件下载)_勤动手多动脑少说多做厚积薄发-CSDN博客_ ...

  8. JS实现点击表头表格自动排序(含数字、字符串、日期)

    <!DOCTYPE> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta h ...

  9. Three.js加载.obj和.mtl文件(无法加载材质、路径错误问题)

    加载.obj模型文件 本文是Three.js电子书的14.3节 使用三维软件导出.obj模型文件的时候,会同时导出一个材质文件.mtl, .obj和.stl文件包含的信息一样都是几何体顶点相关数据,材 ...

最新文章

  1. 招聘:兼职ASP 高级工程师
  2. FFmpeg常用命令总结
  3. 【公测中】阿里云发布国内首个大数据双活容灾服务,满足高要求大数据灾备场景...
  4. linux 多线程编程笔记
  5. 策略模式和工厂模式的区别_java设计模式之状态模式,策略模式孪生兄弟
  6. LeetCode之Search Insert Position
  7. JavaScript对象的创建总结
  8. android手机两种方式获取IP地址
  9. java(15)-策略模式(Strategy Pattern)
  10. Android实现局部图片滑动指引效果
  11. js定位div坐标存入mysql_用JS将页面定位到某个位置(DIV)
  12. 基于spring websocket实现广播及点对点推送功能
  13. 基于时空图卷积网络预测交通流
  14. 介绍3种JavaScript重定向到另一个网页的方法
  15. 为 windows cmd 设置代理
  16. Keil出现“File has been changed outside the editor, reload?”提示
  17. 软件(程序)编写通法
  18. 美学心得(第二百一十七集) 罗国正 (2020年12月)
  19. 新星计划Day2【JavaSE】 枚举类与注解
  20. 十一届蓝桥模拟赛 元辅音字母 JAVA

热门文章

  1. Linux应用编程之dup函数和dup2函数
  2. 【有限元】fluent分析管道两端压力差与管壁摩檫力
  3. Java实现动态代理示例
  4. 6 Matplotlib库实现数据可视化
  5. HTML5期末大作业:鲜花超市网站设计——鲜花超市(4页) HTML+CSS+JavaScript HTML5网页设计成品_学生DW静态网页设计代做_web课程设计网页制作
  6. 如何让SCI期刊审稿人,理解你的文章? - 易智编译EaseEditing
  7. sleep方法的使用,进入sleep状态不释放锁
  8. 监听android home键的实现方式
  9. 微信小程序实现输入框防抖
  10. operater数组的用法