URL.createObjectURL: временное представление файлов
Что такое URL.createObjectURL и зачем он нужен? 🔥
Когда работаешь с файлами в браузере (например, загружаешь изображение или видео), часто нужно создать временную ссылку на этот файл, чтобы отобразить его на странице. Вот тут и приходит на помощь URL.createObjectURL() — он генерирует уникальный URL, который указывает на объект в памяти браузера.
const file = new Blob(['Hello, world!'], { type: 'text/plain' });
const fileUrl = URL.createObjectURL(file);
console.log(fileUrl); // Пример: blob:https://example.com/1a2b3c4d-5e6f-7g8h
Этот URL можно использовать в <a href>, <img src>, <video> и других элементах. Главное — помнить, что ссылка временная и её нужно освобождать вручную!
Как создать и использовать временный URL 🛠️
Допустим, у нас есть <input type="file">, и мы хотим отобразить выбранное изображение на странице. Вот как это сделать:
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) return;
const imageUrl = URL.createObjectURL(file);
const img = document.createElement('img');
img.src = imageUrl;
document.body.appendChild(img);
});
💡 Совет: Всегда проверяйте, что файл существует (
if (!file) return), иначе можно получить ошибку при попытке создать URL дляundefined.
Освобождение памяти: URL.revokeObjectURL
Каждый вызов createObjectURL занимает память в браузере. Чтобы избежать утечек, обязательно освобождайте URL, когда он больше не нужен:
// После использования изображения:
URL.revokeObjectURL(imageUrl);
Теперь браузер может очистить память. Если этого не сделать, ссылка будет висеть до перезагрузки страницы.
⚠️ Важно! Не вызывайте
revokeObjectURLслишком рано — например, сразу после присваиванияimg.src. Дождитесь, пока файл загрузится и отобразится.
Пример: Предпросмотр загружаемого видео 🎥
Давайте создадим мини-приложение для предпросмотра видео перед загрузкой:
const videoInput = document.getElementById('video-upload');
const videoPlayer = document.getElementById('video-preview');
videoInput.addEventListener('change', () => {
const file = videoInput.files[0];
if (!file || !file.type.startsWith('video/')) {
alert('Пожалуйста, выберите видеофайл!');
return;
}
// Освобождаем предыдущий URL, если он был
if (videoPlayer.src) {
URL.revokeObjectURL(videoPlayer.src);
}
const videoUrl = URL.createObjectURL(file);
videoPlayer.src = videoUrl;
videoPlayer.style.display = 'block';
});
Когда использовать createObjectURL, а когда FileReader? 🤔
| Метод | Когда использовать | Плюсы | Минусы |
|---|---|---|---|
URL.createObjectURL |
Для быстрого доступа к файлу в DOM | Мгновенно, не блокирует поток | Требует ручного освобождения |
FileReader |
Для чтения содержимого файла в память | Даёт полный контроль над данными | Асинхронный, сложнее в использовании |
📌 Вывод: Если нужно просто отобразить файл (изображение, видео, PDF через
<iframe>), используйcreateObjectURL. Если требуется прочитать содержимое (например, текст из файла), тогдаFileReader.
Реальный кейс: Drag-and-Drop загрузка с предпросмотром ️
Вот как можно реализовать перетаскивание файлов с мгновенным отображением:
const dropZone = document.getElementById('drop-zone');
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('dragover');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('dragover');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('dragover');
const file = e.dataTransfer.files[0];
if (!file.type.startsWith('image/')) return;
const img = new Image();
img.src = URL.createObjectURL(file);
img.onload = () => {
document.body.appendChild(img);
URL.revokeObjectURL(img.src); // Можно вызвать после onload
};
});
Частые ошибки и как их избежать 🚨
-
Утечка памяти: забывают вызвать
revokeObjectURL.
Решение: Используйтеrevoke, когда URL больше не нужен. -
Слишком ранний вызов
revoke: например, до загрузки изображения.
Решение: Вызывайтеrevokeпосле событийonload/onerror. -
Использование для больших файлов:
createObjectURLхранит файл в памяти.
Решение: Для огромных файлов лучше использоватьFileReaderили загружать на сервер.
Под капотом: как это работает? 🔍
Когда вызываешь URL.createObjectURL(blob), браузер:
- Создает уникальный URL вида
blob:<origin>/<uuid>. - Связывает его с Blob/File в памяти.
- Возвращает строку, которую можно использовать в DOM.
При переходе по такому URL браузер ищет связанный Blob и отдает его содержимое, как если бы это был обычный файл на сервере.
Итоги: ключевые мысли 💎
URL.createObjectURL()— мощный инструмент для работы с файлами прямо в браузере.- Всегда освобождай URL через
revokeObjectURL, когда он не нужен. - Идеально подходит для предпросмотра изображений, видео, PDF.
- Для чтения содержимого файлов используй
FileReader.
Теперь ты готов эффективно работать с файлами в JavaScript! Попробуй применить эти знания в своём следующем проекте. 😉