当前位置:   article > 正文

Web 开发中 Blob 与 FileAPI 使用简述

file.thumb

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

Web 开发中 Blob 与 FileAPI 使用简述

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

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

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

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

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

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

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

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

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

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

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

  1. const cbd = e.clipboardData;
  2. const fr = new FileReader();
  3. for (let i = 0; i < cbd.items.length; i++) {
  4. const item = cbd.items[i];
  5. if (item.kind == 'file') {
  6. const blob = item.getAsFile();
  7. if (blob.size === 0) {
  8. return;
  9. }
  10. previewFile(blob);
  11. }
  12. }

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

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

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

  1. function onInitFs(fs) {
  2. fs.root.getFile(
  3. 'log.txt',
  4. { create: true },
  5. function(fileEntry) {
  6. // Create a FileWriter object for our FileEntry (log.txt).
  7. fileEntry.createWriter(function(fileWriter) {
  8. fileWriter.onwriteend = function(e) {
  9. console.log('Write completed.');
  10. };
  11. fileWriter.onerror = function(e) {
  12. console.log('Write failed: ' + e.toString());
  13. };
  14. // Create a new Blob and write it to log.txt.
  15. var blob = new Blob(['Lorem Ipsum'], { type: 'text/plain' });
  16. fileWriter.write(blob);
  17. }, errorHandler);
  18. },
  19. errorHandler
  20. );
  21. }
  22. window.requestFileSystem(window.TEMPORARY, 1024 * 1024, onInitFs, errorHandler);
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/145099?site
推荐阅读
相关标签
  

闽ICP备14008679号