Web 开发中 Blob 与 FileAPI 使用简述

开发 开发工具
本文节选自 Awesome CheatSheet/DOM CheatSheet,主要是对 DOM 操作中常见的 Blob、File API 相关概念进行简要描述。

 本文节选自 Awesome CheatSheet/DOM CheatSheet,主要是对 DOM 操作中常见的 Blob、File API 相关概念进行简要描述。

[[238178]]

Web 开发中 Blob 与 FileAPI 使用简述

Blob 是 JavaScript 中的对象,表示不可变的类文件对象,里面可以存储大量的二进制编码格式的数据。Blob 对象的创建方式与其他并无区别,构造函数可接受数据序列与类型描述两个参数:

const debug = { hello: 'world' };let blob = new Blob([JSON.stringify(debug, null, 2)], { 
  type: 'application/json'});// Blob(22) {size: 22, type: "application/json"}// 也可以转化为类 URL 格式const url = URL.createObjectURL(blob);// "blob:https://developer.mozilla.org/88c5b6de-3735-4e02-8937-a16cc3b0e852"// 设置自定义的样式类blob = new Blob(['body { background-color: yellow; }'], { 
  type: 'text/css'}); 
 
link = document.createElement('link'); 
link.rel = 'stylesheet';//createObjectURL returns a blob URL as a string.link.href = URL.createObjectURL(blob); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

其他的类型转化为 Blob 对象可以参考 covertToBlob.js,将 Base64 编码的字符串或者 DataUrl 转化为 Blob 对象。Blob 包括了 size 与 type,以及常用的用于截取的 slice 方法等属性。Blob 对象能够添加到表单中,作为上传数据使用:

const content = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...const blob = new Blob([content], { type: 'text/xml' }); 
formData.append('webmasterfile', blob); 
  • 1.
  • 2.

slice 方法会返回一个新的 Blob 对象,包含了源 Blob 对象中指定范围内的数据。其实就是对这个 blob 中的数据进行切割,我们在对文件进行分片上传的时候需要使用到这个方法,即把一个需要上传的文件进行切割,然后分别进行上传到服务器:

const BYTES_PER_CHUNK = 1024 * 1024; // 每个文件切片大小定为1MB .const blob = document.getElementById('file').files[0];const slices = Math.ceil(blob.size / BYTES_PER_CHUNK);const blobs = [];Array.from({ length: slices }).forEach(function(item, index) { 
  blobs.push(blob.slice(indexindex + 1)); 
}); 
  • 1.
  • 2.
  • 3.

这里我们使用的 blob 对象实际上是 HTML5 中的 File 对象;HTML5 File API 允许我们对本地文件进行读取、上传等操作,主要包含三个对象:File,FileList 与用于读取数据的 FileReader。File 对象就是 Blob 的分支,或者说子集,表示包含某些元数据的单一文件对象;FileList 即是文件对象的列表。FileReader 能够用于从 Blob 对象中读取数据,包含了一系列读取文件的方法与事件回调,其基本用法如下:

const reader = new FileReader(); 
reader.addEventListener('loadend'function() { 
  // reader.result 包含了 Typed Array 格式的 Blob 内容}); 
reader.readAsArrayBuffer(blob); 
 
blob = new Blob(['This is my blob content'], { type: 'text/plain' }); 
read.readAsText(bolb); // 读取为文本// reader.readAsArrayBuffer   //将读取结果封装成 ArrayBuffer ,如果想使用一般需要转换成 Int8Array 或 DataView// reader.readAsBinaryString  // 在IE浏览器中不支持改方法// reader.readAsTex // 该方法有两个参数,其中第二个参数是文本的编码方式,默认值为 UTF-8// reader.readAsDataURL  // 读取结果为DataURL// reader.readyState // 上传中的状态 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

在图片上传中,我们常常需要获取到本地图片的预览,参考 antd/Upload 中的处理:

// 将文件读取为 DataURLconst previewFile = (file: File, callback: Function) => { 
  const reader = new FileReader(); 
  reader.onloadend = () => callback(reader.result); 
  reader.readAsDataURL(file); 
}; 
// 设置文件的 DataUrlpreviewFile(file.originFileObj, (previewDataUrl: string) => { 
  file.thumbUrl = previewDataUrl; 
}); 
// JSX<img src={file.thumbUrl || file.url} alt={file.name} />; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

另一个常用的场景就是获取剪贴板中的图片,并将其预览展示,可以参考 coding-snippets/image-paste:

const cbd = e.clipboardData;const fr = new FileReader(); 
for (let i = 0; i < cbd.items.length; i++) { 
  const item = cbd.items[i]; 
 
  if (item.kind == 'file') { 
    const blob = item.getAsFile(); 
    if (blob.size === 0) { 
      return
    } 
 
    previewFile(blob); 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

标准的 Web 标准中提供了 FileReader 对象进行读取操作,不过 Chrome 中提供了 FileWriter 对象,允许我们在浏览器沙盒中创建文件,其基于 requestFileSystem 方法:

// 仅可用于 Chrome 浏览器中window.requestFileSystem = 
  window.requestFileSystem || window.webkitRequestFileSystem; 
window.requestFileSystem(type, size, successCallback, opt_errorCallback); 
  • 1.
  • 2.
  • 3.

简单的文件创建与写入如下所示:

function onInitFs(fs) { 
  fs.root.getFile( 
    'log.txt'
    { createtrue }, 
    function(fileEntry) { 
      // Create a FileWriter object for our FileEntry (log.txt).      fileEntry.createWriter(function(fileWriter) { 
        fileWriter.onwriteend = function(e) { 
          console.log('Write completed.'); 
        }; 
 
        fileWriter.onerror = function(e) { 
          console.log('Write failed: ' + e.toString()); 
        }; 
 
        // Create a new Blob and write it to log.txt.        var blob = new Blob(['Lorem Ipsum'], { type: 'text/plain' }); 
 
        fileWriter.write(blob); 
      }, errorHandler); 
    }, 
    errorHandler 
  ); 

window.requestFileSystem(window.TEMPORARY, 1024 * 1024, onInitFs, errorHandler); 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

 【本文是51CTO专栏作者“张梓雄 ”的原创文章,如需转载请通过51CTO与作者联系】

戳这里,看该作者更多好文

 

责任编辑:武晓燕 来源: 51CTO专栏
相关推荐

2009-07-06 10:49:34

Web开发

2022-07-25 20:43:28

Web

2012-02-23 10:32:19

HTML 5

2011-08-17 15:10:21

iPhone开发Web视图

2009-09-22 11:49:34

ibmdwREST

2010-08-02 16:23:25

ibmdwWebSphereWeb2.0

2010-09-14 09:19:40

2009-11-23 14:38:02

Visual Stud

2015-09-17 11:04:46

2009-03-09 10:28:45

AJAXASP.NETWEB

2009-07-29 09:38:06

Web开发ASP.NET

2010-06-24 08:55:11

Web开发Web设计Web语言

2024-07-01 00:00:06

ASP.NET开源

2015-06-25 15:56:08

2014-12-24 09:54:30

2009-07-15 16:26:04

iBATIS Clob

2011-08-23 17:52:39

LUAWeb 开发

2011-03-24 11:37:41

Hibernate

2019-11-25 11:20:08

FlutterWeb应用软件开发

2013-04-11 12:40:16

Android消息机制
点赞
收藏

51CTO技术栈公众号