Краткое введение в использование Blob и FileAPI в веб-разработке

внешний интерфейс сервер JavaScript Chrome

Эта статья взята изAwesome CheatSheet/DOM CheatSheet, в основном для краткого описания общих концепций, связанных с Blob и File API в операциях DOM.

Краткое введение в использование 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);

Преобразование других типов в объекты Blob может ссылаться наcovertToBlob.js, который преобразует строку или DataUrl в кодировке Base64 в объект Blob. Большой двоичный объект включает в себя такие свойства, как размер и тип, а также часто используемый метод среза для перехвата. Объекты 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);

Метод slice возвращает новый объект 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(index, index + 1));
});

Объект blob, который мы используем здесь, на самом деле является объектом File в HTML5; File API HTML5 позволяет нам читать и загружать локальные файлы, в основном включая три объекта: 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 // 上传中的状态

При загрузке изображения нам часто нужно получить предварительный просмотр локального изображения, см.antd/UploadОбработка в:

// 将文件读取为 DataURL
const previewFile = (file: File, callback: Function) => {
  const reader = new FileReader();
  reader.onloadend = () => callback(reader.result);
  reader.readAsDataURL(file);
};

// 设置文件的 DataUrl
previewFile(file.originFileObj, (previewDataUrl: string) => {
  file.thumbUrl = previewDataUrl;
});

// JSX
<img src={file.thumbUrl || file.url} alt={file.name} />;

Другой распространенный сценарий — получить изображение в буфер обмена и просмотреть его, вы можете обратиться к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);
  }
}

Стандартный веб-стандарт предоставляет объект FileReader для чтения, но Chrome предоставляет объект FileWriter, который позволяет нам создавать файлы в песочнице браузера на основе метода requestFileSystem:

// 仅可用于 Chrome 浏览器中
window.requestFileSystem =
  window.requestFileSystem || window.webkitRequestFileSystem;

window.requestFileSystem(type, size, successCallback, opt_errorCallback);

Простое создание и запись файлов выглядит следующим образом:

function onInitFs(fs) {
  fs.root.getFile(
    'log.txt',
    { create: true },
    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);