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 => {
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" onchange="f(this)"></input>
<script>
function f(e) {
e.files
}
</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) {
}
}
})
}
}
})
}
}
})
看上面的回调,一套一套的,确实不好维护。下面使用Promise写法,这样就可以像处理同步一样处理嵌套的调用了。这里也可以return返回想要的值。
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 => {
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>
-
方法 具体怎么使用这些方法,看上面的例子。 readAsArrayBuffer() ? 直接返回文件的二进制数据,可以分片上传到后端 readAsDataURL() ? 返回一串base64字符串,直接放到img的src上面显示图片 readAsText() ? 读取字符串
7.7 ArrayBuffer
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer ArrayBuffer的API
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 => {
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是发送的数据体
最后的文档还写了,下面的数据都可以传,包括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('失败回调')
}
|