分片 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 来用于数据操作。

  • 能做什么?

    我直接说能干嘛把。

    1. 显示图片

      <!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>
      
    2. 拿原始二进制数据

      <!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" 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>
    
  • 方法

    具体怎么使用这些方法,看上面的例子。

    readAsArrayBuffer()

    ​ 直接返回文件的二进制数据,可以分片上传到后端

    readAsDataURL()

    ​ 返回一串base64字符串,直接放到img的src上面显示图片

    readAsText()

    ​ 读取字符串

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是发送的数据体

    最后的文档还写了,下面的数据都可以传,包括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('失败回调')
}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐