博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
那些前端二进制操作API
阅读量:4992 次
发布时间:2019-06-12

本文共 3903 字,大约阅读时间需要 13 分钟。

一直以来,前端的工作主要涉及的是字符串操作,而对二进制的数据接触较少。但是这种需求却一直存在着,尤其是HTML5之后,随着web应用越来越复杂,File,Blob,TypedArray这些API的出现使得前端对二进制的操作更加方便。

3591556009557_.pic.jpg

atob,btoa

这两个函数的应用场景之一是解密大佬留下的微信号?,函数名中的a,b分别代表 ASCII 和 binary string。谈到这两个函数就不得不提到base64。Base64就是一种基于64个可打印字符来表示二进制数据的方法.Base64 encode得到的字符串是ASCII码的子集。那么什么又是binary string呢? 设计的目的是用来代表和操作二进制数据,而不是用来编码字符串的。

为什么中文不能使用atob,btoa函数?因为binary string的范围是0-255,中文utf-8已经超过这个范围了。讲解了字符编码(ASCII LATIN1 UTF8)相关知识。

base64编码规则

参考:

以对'A'base64编码为例:

btoa('A') //"QQ=="

根据base64的原理,我们试着自己实现一下:

//1. charcode'A'.charCodeAt().toString(2) //"1000001"//7位前面补成8位 加一个0"1000001".padStart(8, '0') //"01000001"//3. 为了达到24位的整数倍,补两个0x00"01000001" + '00'.repeat(8) //"010000010000000000000000"//4. 按6位一组分开["010000", "010000", "000000", "000000"]=> [16,16,0,0] => [Q,Q,A,A]//查表得到字符串,两个==表示补了两字节0x00,也取代了原来的A的作用,补了0x00之后,生成的base64字符串末尾肯定是0`QQ==`

综上所述,经过base64编码得到的字符串长度一定是4的倍数。末尾可能有0,1,2个等号,用来表示在编码时补位的个数。

JS字符集

'?'.length// 2'?'.charCodeAt().toString(16)//"d83d"'?'.charCodeAt(1).toString(16)//"de02""\ud83d\ude02"//"?"

encodeURIComponent('中')为什么得到 "%E4%B8%AD"

首先我们要知道,接下来会分以下几步

'中'.charCodeAt(0) // 20013(20013).toString(2) // 得到"100111000101101" 15位,//1 先高位补一个0凑成16位"0100111000101101",//2 再按UTF-8编码规则,1110 {4} 10 {6} 10 {6}得到24位 111001001011100010101101//3 再拆分成8位一组。[11100100,10111000,10101101]//4 再2进制转换成16进制["e4", "b8", "ad"]//5 最后toUpperCase,%连接

File

在浏览器中,我们可以通过File api操作文件,我们可以通过input元素拿到file,也可以直接调用构造函数创建一个file实例

// 从input元素中读取一个文件:let fileInput = document.getElementById('file')fileInput.onchange = console.log(fileInput.files[0])// 直接创建一个let file = new File(['1'], '1.txt')file instanceof File // truefile instanceof Blob // true

file和其他类型之间的转换是一个异步的过程,是通过fileReader来实现的,转换的结果在reader的onload事件中获取,代码如下:

  • file to base64

dataUrl除去MIME信息以外才是base64的数据

let reader = new FileReader();reader.onload = event => console.log(event.target.result);reader.readAsDataURL(file);
  • file to arrayBuffer
let reader = new FileReader(file);reader.onload = event => console.log(event.target.result)reader.readAsArrayBuffer(file);
  • file to binaryString
reader.readAsBinaryString(file)
  • base64 to file
function dataURLtoFile(dataurl, filename) {  let 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 File([u8arr], filename, {type:mime});}

MIME

(通常称为 Multipurpose Internet Mail Extensions 或 MIME 类型 )是一种标准,用来表示文档、文件或字节流的性质和格式。

所有的MIME类型可以在这里找到:

再提一下文件编码格式,,使用hexdump命令可以查看文件的二进制编码。

canvas.toBlob canvas.toDataURL

// 异步,blob会被传到callback的参数中canvas.toBlob(callback, mimeType, qualityArgument);//同步canvas.toDataURL(type, encoderOptions);

window.URL.createObjectURL

objectURL = URL.createObjectURL(blob);//"blob:https://i.cnblogs.com/64556585-a84a-450c-b7a3-bd54a51b5fdd"

爱奇艺的视频地址使用这种方式

blob和arrayBuffer

blob和arraybuffer的区别可以看

将blob转成arrayBuffer: blob => FileReader.readAsArrayBuffer => arrayBuffer

直接创建个arrayBuffer

new ArrayBuffer(length)

TypedArray(uint8Array...)

typedArray不是一个api,而是一类api的统称,它们被设计用来操作arrayBuffer,但是不能直接接收blob,构造函数如下:

new TypedArray(length);new TypedArray(typedArray);new TypedArray(object);new TypedArray(buffer [, byteOffset [, length]]);

TypedArray和arrayBuffer的关系

typedArray是操作arrayBuffer的方式

TypedArray之间的区别

元素的容量不同,详见:

比如:Int8Array元素大小1字节,Int16Array每个元素占2字节

web和二进制数据

xhr2, fetch,Response,Request,Body

res.json() res.text() res.arrayBuffer()

当后端以流的形式返回一个图片时:

uploading-image-583828.png

fetch(imgurl).then(res => {            return res.blob()          }).then(blob => {           if (blob) {                    // 以objectUrl形式显示          img.src = URL.createObjectURL(blob);                     // 以dataUrl形式显示图片            let reader = new FileReader(blob);            reader.onload = event => {              img.src = event.target.result;             }            reader.readAsDataURL(blob);          }

向worker传递二进制数据

直接传递即可

参考:

转载于:https://www.cnblogs.com/imgss/p/10643174.html

你可能感兴趣的文章
Android 深入解析光传感器(二)
查看>>
Ansible@一个高效的配置管理工具--Ansible configure management--翻译(八)
查看>>
【bzoj4552/Tjoi2016&Heoi2016】排序——二分+线段树/平衡树+线段树分裂与合并
查看>>
Windows Internals学习笔记(八)IO系统
查看>>
sql插件,SQLPrompt
查看>>
Objetive-C 属性和线程安全
查看>>
mybatis pagehelper实现分页
查看>>
很牛的javascript日期转换函数
查看>>
javascript格式化json显示
查看>>
Redis 在 SNS 类应用中的最佳实践有哪些?
查看>>
关于Unity 动画绘制原理
查看>>
django-xadmin后台开发
查看>>
Canvas链式操作
查看>>
学渣乱搞系列之网络流学习
查看>>
Acdream A - Unique Attack
查看>>
java遍历List的多种方法
查看>>
【投票】你心目中的Excel催化剂价值有多大(附主流国内外收费插件供参考)?...
查看>>
算法复习——半平面交(bzoj2618凸多边形)
查看>>
关于在Intellij Idea中使用JSTL标签库报错的问题
查看>>
如何用自己电脑做服务器,绑定域名建一个个人网站
查看>>