JavaScript Blob
Узнайте, как использовать объекты Blob в JavaScript: создавайте и нарезайте Blob, генерируйте и отзывайте Blob URL, читайте содержимое и конвертируйте в Base64.
Blob (сокращение от Binary Large Object) представляет собой неизменяемые необработанные данные, похожие на файл. Это стандартный способ передачи фрагментов двоичного содержимого в браузере — текст, изображения, аудио, PDF-файлы и всё остальное — без преобразования в собственный тип JavaScript, такой как string или Array. Blob является непрозрачным: он хранит байты и MIME-тип type, а сами байты вы считываете асинхронно по мере необходимости.
Blob-объекты занимают центральное место в работе с файлами в вебе. File — это специализированный Blob с именем и датой изменения, fetch() может вернуть тело ответа в виде Blob, а canvas, буфер обмена и механизм загрузки файлов — все они работают с Blob. В этом руководстве рассматривается создание, нарезка, связывание, чтение и конвертация Blob, а также типичные ошибки, с которыми сталкиваются разработчики.
Что такое Blob на самом деле
Blob предоставляет два свойства только для чтения и несколько асинхронных методов чтения:
blob.size— длина данных в байтах.blob.type— строка MIME-типа (пустая"", если тип не был указан).blob.slice(start, end, type)— возвращает новый Blob для диапазона байтов без копирования исходных данных.blob.text(),blob.arrayBuffer(),blob.bytes(),blob.stream()— методы чтения на основе промисов (или потоков).
Поскольку Blob неизменяем, ни один из этих методов не изменяет оригинал — они всегда возвращают новый Blob или новое считывание байтов.
Создание объектов Blob
Blob создаётся с помощью конструктора, который принимает два аргумента: массив частей и необязательный объект options.
new Blob(parts, options);Каждый элемент в parts может быть строкой, ArrayBuffer, TypedArray/DataView или другим Blob — они объединяются по порядку. Строка options.type задаёт MIME-тип, который сообщает потребителям, как интерпретировать байты (например "text/plain", "image/jpeg", "application/json" или "audio/mpeg"). Смотрите MIME types для полного обзора.
Объединение и нарезка Blob-объектов
Поскольку Blob-объекты неизменяемы, их «редактирование» заключается в создании нового Blob из существующих частей. В массиве частей можно свободно смешивать строки и Blob-объекты:
Чтобы извлечь диапазон байтов, используйте blob.slice(start, end). Метод работает аналогично Array.prototype.slice: end не включается в результат, а отрицательные индексы отсчитываются с конца.
Работа с Blob URL
Blob URL (также называемый object URL) — это кратковременный URL вида blob:, указывающий на Blob, хранящийся в памяти. Его можно использовать везде, где ожидается URL — в атрибуте <img src>, в ссылке <a href> для скачивания, в элементе <audio> — и браузер будет читать Blob так, как если бы это был удалённый ресурс.
Генерация Blob URL
URL.createObjectURL(blob) возвращает уникальный URL при каждом вызове:
Отзыв Blob URL
Каждый object URL удерживает свой Blob в памяти до тех пор, пока документ не будет выгружен — даже после того, как использующий его элемент удалён. Чтобы избежать утечек памяти, вызывайте URL.revokeObjectURL(url) после того, как URL стал не нужен:
const data = new Blob(["Example text"], { type: "text/plain" });
const blobUrl = URL.createObjectURL(data);
// ...use blobUrl, e.g. as an <a href> or <img src> ...
URL.revokeObjectURL(blobUrl); // frees the memory held by the Blob URLЗапуск скачивания файла
Распространённый практический сценарий — позволить пользователю скачать данные, сгенерированные скриптом, без обращения к серверу. Создайте Blob, оберните его в object URL, кликните по временной ссылке, затем отзовите URL:
function downloadText(filename, text) {
const blob = new Blob([text], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename; // suggested file name
a.click();
URL.revokeObjectURL(url); // clean up immediately after the click
}
downloadText("notes.txt", "Saved from the browser!");Чтение содержимого Blob
Современные методы чтения на основе промисов — самый простой способ получить байты из Blob:
Более старый API FileReader выполняет ту же задачу, но использует события вместо промисов. Он по-прежнему полезен, когда нужны события прогресса или требуется поддержка устаревшего кода:
Для очень больших Blob можно потоково считывать байты с помощью blob.stream() вместо загрузки всего содержимого в память сразу, а blob.arrayBuffer() предоставляет доступ к «сырому» ArrayBuffer для низкоуровневой работы с двоичными данными.
Конвертация Blob в Base64
Base64 позволяет встраивать двоичные данные в текстовые контексты — например, в JSON-пейлоады или data URL. FileReader.readAsDataURL() формирует URL вида data:, полезная нагрузка которого закодирована в Base64:
Типичные ошибки
- Blob неизменяем. Не существует метода для дополнения или перезаписи Blob — создавайте новый из нужных частей.
- Чтение всегда асинхронно.
text(),arrayBuffer()иFileReaderвозвращают результаты с задержкой, поэтому используйтеawaitили.then(); байты никогда не доступны синхронно. sizeсчитает байты, а не символы. Многобайтовые UTF-8 символы увеличивают счётчик:new Blob(["é"]).sizeравно2, а не1.- Отзывайте ваши object URL. Забытый
createObjectURLудерживает Blob в памяти на всё время жизни страницы. type— это просто метка. Указаниеtype: "image/png"не проверяет, что байты действительно являются PNG; это лишь объявляет предполагаемый MIME-тип.
Где используется Blob
- Загрузка файлов на сервер. Отправляйте Blob (или
File) в теле запросаfetch(), при необходимости внутриFormData. - Генерируемые загрузки. Создавайте CSV, JSON или текст на лету и передавайте пользователю через object URL, как показано выше.
- Работа с canvas и изображениями.
canvas.toBlob(callback, type)преобразует<canvas>в Blob с изображением, который можно загрузить на сервер или предложить для скачивания. - Потоковая передача больших данных. Нарезайте и передавайте потоком большие двоичные данные без единовременной загрузки всего содержимого в память.
Заключение
Blob — это контейнер браузера для неизменяемых необработанных двоичных данных: создайте его из строк или буферов, нарежьте без копирования, свяжите через object URL и считайте обратно с помощью text(), arrayBuffer() или FileReader. Помните, что Blob неизменяем, чтение происходит асинхронно, а object URL необходимо отзывать. Соблюдая эти правила, вы сможете работать с файлами, генерировать загрузки и обрабатывать медиаданные полностью на стороне клиента.
Для более глубокого изучения познакомьтесь с API File и FileReader и ArrayBuffer и типизированными массивами.