Js 二进制知识点
7.1 blobhttps://www.jianshu.com/p/b322c2d5d778 Blob 的一些用法https://developer.mozilla.org/zh-CN/docs/Web/API/BlobBlob的APIBlob 表示一个不可变的、原始数据的类文件对象, 它的数据可以按文本、二进制读取,也可以转换成 ReadableStream 来用于数据操作。能做什么?我直接说能
分片 Java + 前端
https://blog.csdn.net/qq_45716444/article/details/121756335
7.1 blob
https://www.jianshu.com/p/b322c2d5d778 Blob 的一些用法
https://developer.mozilla.org/zh-CN/docs/Web/API/Blob Blob的API
Blob
表示一个不可变的、原始数据的类文件对象, 它的数据可以按文本、二进制读取,也可以转换成 ReadableStream
来用于数据操作。
-
能做什么?
我直接说能干嘛把。
-
显示图片
<!DOCTYPE html> <html lang="en"> <body> <input type="file" id="txt" onchange="f(this)"></input> <div style="display: inline-block;width: 100px;"> <img id="img" style="width: 100%;"> </div> </body> <script> function f(e) { const file = e.files[0] const blob = file.slice(0, file.size) document.getElementById('img').src = URL.createObjectURL(blob) } </script> </html>
-
拿原始二进制数据
<!DOCTYPE html> <html lang="en"> <body> <input type="file" id="txt" onchange="f(this)"></input> </body> <script> function f(e) { const { log, error } = console const file = e.files[0] const blob = file.slice(0, file.size) blob.arrayBuffer().then(res => { // 因为文件类型最小的单位是byte,所以使用Int8Array来接受 // res 返回一个ArrayBuffer数据类型,文章下面有解释 const int8Array = new Int8Array(res) for (let i = 0; i < int8Array.length; i++) { log(int8Array[i]) } }).catch(error => { error(error) }) } </script> </html>
-
7.2 File
https://developer.mozilla.org/zh-CN/docs/Web/API/File 有一句话如下:
通常情况下, File
对象是来自用户在一个 input
元素上选择文件后返回的 FileList
对象,也可以是来自由拖放操作生成的 DataTransfer
对象,或者来自 HTMLCanvasElement
上的 mozGetAsFile
() API。
这句话说了File主要来自三处地方
input
type=file
- 自由拖放生成的
DataTransfer
对象 HTMLCanvasElement
上的mozGetAsFile
()
这里我主要关注第一种获取方式
<!-- 第一种写法 -->
<input type="file" onchange="f(this)"></input>
<script>
function f(e) {
e.files // 这就是FileList
}
</script>
<!-- 第二种写法 -->
<input type="file"></input>
<script>
window.onload = () => {
document.getElementsByTagName('input')[0].onchange = function (e) {
e.files
}
}
</script>
File也可以使用slice转成Blob,Blob有拿到文件 二进制、字符串文本 等方法,也可以转换成 ReadableStream
来用于数据操作。不然就使用FileReader拿到File里边的数据。
7.3 FileList
FileList 比较简单,它就是保存了一组File元素的集合。它本身只有一个方法和一个属性,方法是item、接受一个下标、访问元素。属性
length表示元素的个数
const l = e.files
for (let i = 0; i < l.length; i++) {
l.item(i) //访问元素
}
7.4 二进制文件格式
https://zhuanlan.zhihu.com/p/20693043
7.5 Promise
https://es6.ruanyifeng.com/#docs/promise 简介和用法,建议去里面看
Promise是es6新增的特性,外部调用它是异步的,这是给我最大的感觉。它有三种状态 pending(进行中) fulfilled(已成功) rejected(已失败),Promise只能从pending 转其它两种状态,之后就不能更换状态,成功或失败状态都会对应后面回调的函数。下面举例简单的使用:
console.log('1')
new Promise((resolve, reject) => {
setTimeout(resolve('2'), 2000)
}).then(res => {
console.log(res)
})
console.log('3')
运行结果是132
https://www.cnblogs.com/tcz1018/p/14103642.html 这个大佬比较了传统的回调函数和es6的Promise,道出了回调函数的不足,Promise 的优点及缺点,这里做重点的总结举例,但是不写缺点,因为我不知道这些缺点在开发中有什么不利的影响。
-
Promise 优点
Promise是一种异步编程的解决方案,比传统的 – 回调函数和事件 – 更合理更强大。
拿回调函数和Promise做一个小比较,我们常用的(Jquery的ajax)$.ajax,里面success就是一个回调函数,有时候一个请求依赖另一个请求的结果,当这种依赖关系多了之后就会形成回调地狱,不利于代码的维护。而且回调函数会剥夺函数的return功能。对于这两种情况Promise的处理会更好。// 回调地狱举例 $.ajax({ type: 'JSON', url: '', success: function (res) { if (res && res.code === 200) { // 开始新的请求 $.ajax({ type: 'JSON', url: '', data: res.data, success: function (res) { if (res && res.code === 200) { // 又开始新的请求 $.ajax({ type: 'JSON', url: '', data: res.data, success: function (res) { if (res && res.code === 200) { // 这里想return } } }) } } }) } } })
看上面的回调,一套一套的,确实不好维护。下面使用Promise写法,这样就可以像处理同步一样处理嵌套的调用了。这里也可以return返回想要的值。
// 比较上面ajax的写法,会发现这种链式的调用好很多 let url = 'xxx' new Promise((resolve, reject) => { $.ajax({ type: 'JSON', url: '', data: {}, success: function (res) { if (res && res.code === 200) { resolve(res) } } }) }).then(res => { $.ajax({ type: 'JSON', url: '', data: res, success: function (res) { if (res && res.code === 200) { resolve(res.data) } } }) }).then(res => { $.ajax({ type: 'JSON', url: '', data: res, success: function (res) { if (res && res.code === 200) { resolve(res.data) } } }) }).then(res => { // 最后拿到数据 console.log(res) return res }).then(res => { // 拿到return 返回的值,举例能return而已 console.log(res) })
7.6 FileReader
https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader FileReader的API
简单来说,FileReader能异步读取File和Blob的数据。
-
事件
好多事件,我只列举两个,onload 读取成功时触发,onerror 读取失败时触发。
<!DOCTYPE html> <html lang="en"> <body> <input type="file" id="txt" onchange="f(this)"></input> <div style="display: inline-block;width: 100px;"> <img id="img" style="width: 100%;"> </div> </body> <script> function f(e) { const file = e.files[0] var reader = new FileReader(); // 成功读取 reader.addEventListener("load", function(e) { document.getElementById('img').src = e.target.result }); reader.addEventListener("error", function(e) { console.log('读取文件失败') }) reader.readAsDataURL(file); } </script> </html>
-
方法
具体怎么使用这些方法,看上面的例子。
直接返回文件的二进制数据,可以分片上传到后端
返回一串base64字符串,直接放到img的src上面显示图片
读取字符串
7.7 ArrayBuffer
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer ArrayBuffer的API
拿来做文件加密,具体是不是我不太清楚。文件加密不是Blob就是Array Buffer。
7.7.1 内容
这句话很重要:你不能直接操作 ArrayBuffer
的内容,而是要通过类型数组对象或 DataView
对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。
-
类型数组对象 对 ArrayBuffer 的操作
<!DOCTYPE html> <html lang="en"> <body> <input type="file" id="txt" onchange="f(this)"></input> </body> <script> function f(e) { const { log, error } = console const file = e.files[0] const blob = file.slice(0, file.size) blob.arrayBuffer().then(res => { // 因为文件类型最小的单位是byte,所以使用Int8Array来接受 const int8Array = new Int8Array(res) for (let i = 0; i < int8Array.length; i++) { log(int8Array[i]) } }).catch(error => { error(error) }) } </script> </html>
-
DataView 对 ArrayBuffer 的操作
这里跟上面有一个区别,就是关于字节序概念,这个就不介绍了,头疼…
7.7.2 前端文件md5加密
MD5 现成js代码下载 https://github.com/emn178/js-md5
// 上面链接的代码,放到相同目录下,引入
const x = import('./md5.min.js')
function buf2hex(buffer) {
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
x.then(md5 => {
// 加密之后返回的字符串
console.log(buf2hex(md5.default.arrayBuffer(new ArrayBuffer(10))))
})
7.8 XMLHttpRequest
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest API文档
我们来关注下面这些东西
-
open
// 语法,async是否异步 xhrReq.open(method, url); xhrReq.open(method, url, async);
-
send
XMLHttpRequest.send(body)
下面语法重点说一下body,body是发送的数据体
-
可以为
Document
, 在这种情况下,它在发送之前被序列化。这里就是说我们可以传入HTMLDocument、XMLDocuement,也就是把整个网页都上传,它会自己序列化
-
为
XMLHttpRequestBodyInit
, 从 per the Fetch spec (规范中)可以是Blob
,BufferSource
(en-US),FormData
,URLSearchParams
, 或者USVString
对象. -
null
最后的文档还写了,下面的数据都可以传,包括ArrayBuffer。
XMLHttpRequest.send(); XMLHttpRequest.send(ArrayBuffer data); XMLHttpRequest.send(ArrayBufferView data); XMLHttpRequest.send(Blob data); XMLHttpRequest.send(Document data); XMLHttpRequest.send(DOMString? data); XMLHttpRequest.send(FormData data);
-
事件
-
load 成功之后调用
-
error 失败之后调用
-
onprogress
可以做上传进度
- 接受一个回调函数
- 回调函数返回两个值
event.loaded
已传输的数据量event.total
总共的数据量
const xhr = new XMLHttpRequest()
xhr.open(method, url, true)
xhr.onprogress = function(e){
e.loaded
e.total
}
xhr.send(new ArrayBuffer)
xhr.onload = () => {
console.log('成功回调')
}
xhr.onerror = (err) => {
console.error('失败回调')
}
更多推荐
所有评论(0)