Blob对象的了解和使用

Blob

概念

Blob对象表示不可变的类似文件对象的原始数据。Blob表示不一定是JavaScript原生形式的数据。 File 接口基于Blob,继承了 blob的功能并将其扩展使其支持用户系统上的文件。

File接口

文件(File) 接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容。

通常情况下, File 对象是来自用户在一个input元素上选择文件后返回的 FileList 对象,也可以是来自由拖放操作生成的 DataTransfer 对象,或者来自 HTMLCanvasElement 上的 mozGetAsFile() API。在Gecko中,特权代码可以创建代表任何本地文件的File对象,而无需用户交互(有关详细信息,请参阅注意事项。

File 对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中。比如说, FileReader, URL.createObjectURL(), createImageBitmap(), 及 XMLHttpRequest.send() 都能处理 Blob 和 File。

File对象和Blob对象

File对象,就是一个文件,比如我用input type=”file”标签来上传文件,那么里面的每个文件都是一个File对象.

Blob对象,就是二进制数据,比如通过new Blob()创建的对象就是Blob对象

场景

  • 上传
  • 下载
  • 图片展示

URL.createObjectURL()

https://developer.mozilla.org/zh-CN/docs/Web/API/URL/createObjectURL

URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。

objectURL = URL.createObjectURL(blob || file);
objectURL 存在哪里?

URL does not refer to data the exists on the server, it refers to data that your browser currently has in memory, for the current page. It will not be available on other pages, it will not be available in other browsers, and it will not be available from other computers.

URL.revokeObjectURL()

https://developer.mozilla.org/zh-CN/docs/Web/API/URL/revokeObjectURL

每次调用createObjectURL时,即使你已经为同一个文件创建过一个URL,也会创建一个新的URL对象。   如果你不再需要这个对象,需要使用URL.revokeObjectURL()方法释放它。   虽然当页面被关闭,浏览器会自动释放它,但是为了最佳性能和内存使用,当确保不再用得到它时,就应该释放它。

下载文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>file</title>
</head>
<body>
    <input id="file" type="file">
    <button id="btn">click</button>
    <script>
        var file = document.getElementById('file')
        var downloadFile
        file.addEventListener('change', function () {
            // Filelist 对象
            console.log(file.files)
            downloadFile = file.files[0]
            var fileLink = document.createElement('a')
            fileLink.download = 'download.csv'
            var blob = new Blob([downloadFile])
            fileLink.href = URL.createObjectURL(blob)
            document.body.appendChild(fileLink);
        })
        var btn = document.getElementById('btn')
        btn.addEventListener('click', function () {
            console.log('click')
            document.getElementsByTagName('a')[0].click()
        })

    </script>
</body>
</html>

片段上传文件

大文件分割 (slice() 方法) slice() 方法接受三个参数,起始偏移量,结束偏移量,还有可选的 mime 类型。如果 mime 类型,没有设置,那么新的 Blob 对象的 mime 类型和父级一样。 当要上传大文件的时候,此方法非常有用,可以将大文件分割分段,然后各自上传,因为分割之后的 Blob 对象和原始的是独立存在的。

不过目前浏览器实现此方法还没有统一,火狐使用的是 mozSlice() ,Chrome 使用的是 webkitSlice() ,其他浏览器则正常的方式 slice() 可以写一个兼容各浏览器的方法:

function sliceBlob(blob, start, end, type) {  
  type = type || blob.type;  
  if (blob.mozSlice) {  
      return blob.mozSlice(start, end, type);  
  } else if (blob.webkitSlice) {  
      return blob.webkitSlice(start, end type);  
  } else {  
      throw new Error("This doesn't work!");  
  }  
}

图片展示

img的src属性及background的url属性,都可以通过接收图片的网络地址或base64来显示图片,同样的,我们也可以把图片转化为Blob对象,生成URL(URL.createObjectURL(blob))