Книга: JavaScript. Подробное руководство, 6-е издание
22.6.4. URL-адреса, ссылающиеся на двоичные объекты
22.6.4. URL-адреса, ссылающиеся на двоичные объекты
В предыдущих разделах было показано, как можно получить или создать двоичный объект. Теперь мы поговорим о том, что можно делать с полученными или созданными двоичными объектами. Самое простое, что можно сделать с двоичным объектом, - это создать URL-адрес, ссылающийся на него. Такой URL-адрес можно использовать везде, где используются обычные URL-адреса: в элементах DOM, в таблицах стилей и даже при работе с объектом XMLHttpRequest
.
Создаются URL-адреса, ссылающиеся на двоичные объекты, с помощью функции createObjectURL().
На момент написания этих строк проект спецификации и Firefox 4 помещали эту функцию в глобальный объект URL, а броузер Chrome и библиотека Webkit добавляли свой префикс к имени этого объекта, называя его webkitURL. Ранние версии спецификации (и ранние реализации броузеров) помещали эту функцию непосредственно в объект Window
. Чтобы получить возможность переносимым образом создавать URL-адреса, ссылающиеся на двоичные объекты, можно определить вспомогательную функцию, как показано ниже:
var getBlobURL = (window.URL && URL.createObjectURL.bind(URL)) ||
(window.webkitURL && webkitURL.createObjectURL.bind(webkitURL)) ||
window.createObjectURL;
Фоновые потоки выполнения также могут использовать этот прикладной интерфейс и обращаться к тем же функциям, в том же объекте URL (или webkitURL).
Если передать двоичный объект функции createObjectURL(),
она вернет URL-адрес (в виде обычной строки). Этот адрес начинается с названия схемы blob://, за которой следует короткая строка, ссылающаяся на двоичный объект с некоторым уникальным идентификатором. Обратите внимание, что эти URL-адреса совершенно не похожи на URL-адреса data://, которые представляют свое собственное содержимое. URL-адрес, ссылающийся на двоичный объект, - это просто ссылка на объект Blob
, хранящийся в памяти броузера или на диске. URL-адреса вида blob:// также отличаются от URL-адресов file://, которые ссылаются непосредственно на файл в локальной файловой системе, давая возможность увидеть путь к файлу, позволяя просматривать содержимое каталогов и тем самым затрагивая проблемы безопасности.
Пример 22.10 демонстрирует два важных приема. Во-первых, он реализует «площадку для сброса», которая обрабатывает события механизма буксировки мышью (drag-and-drop), имеющие отношение к файлам. Во-вторых, когда пользователь сбросит один или более файлов на эту «площадку», с помощью функции createObjectURL()
для каждого из файлов будет создан URL-адрес и элемент <img>,
чтобы отобразить миниатюры изображений, на которые ссылаются эти URL-адреса.
Пример 22.10. Отображение файлов изображений с использованием URL-adpecoe двоичных объектов
<!DOCTYPE html>
<html><head>
<script>
// На момент написания этих строк создатели Firefox и Webkit еще не пришли
// к соглашению об именовании функции createObjectURL()
var getBlobURL = (window.URL && URL.createObjectURL.bind(URL)) ||
(window.webkitURL && webkitURL.createObjectURL.bind(webkitURL)) ||
window.createObjectURL;
var revokeBlobURL = (window.URL && URL.revokeObjectURL.bind(URL)) ||
(window.webkitURL && webkitURL.revokeObjectURL.bind(webkitURL)) ||
window.revokeObjectURL;
// После загрузки документа добавить обработчики событий к элементу droptarget,
// чтобы он мог обрабатывать сбрасываемые файлы
window.onload = function() {
// Отыскать элемент, к которому следует добавить обработчики событий,
var droptarget = document.getElementByld("droptarget");
// Выделяет элемент droptarget изменением рамки, когда пользователь
// буксирует файлы над ним.
droptarget.ondragenter = function(e) {
// Игнорировать, если буксируется что-то иное, не являющееся файлом.
// Когда будет реализована поддержка атрибута dropzone, определяемого
// спецификацией HTML5, это позволит упростить обработчик,
var types = e.dataTransfer.types;
if (!types ||
(types.contains && types.contains("Files")) ||
(types.indexOf && types.indexOf("Files") != -1)) {
droptarget.classList.add("active"); // Выделить элемент droptarget
return false; // Нас интересует
} // буксируемый объект
};
// Снимает выделение площадки сброса, как только пользователь
// отбуксирует файл за ее пределы
droptarget.ondragleave = function() {
droptarget.classList.remove("active");
};
// Этот обработчик просто сообщает броузеру продолжать посылать события
droptarget.ondragover = function(e) { return false; };
// Когда пользователь сбросит файлы, необходимо получить их URL-адреса
// и отобразить миниатюры,
droptarget.ondrop = function(e) {
var files = e.dataTransfer.files; // Сброшенные файлы
for(var і = 0; і < files.length; i++) { // Обойти все файлы в цикле
var type = files[і].type;
if (type.substrings,6) !== "image/") // Пропустить не являющиеся
continue; // изображениями
var img = document.createElement("img"); // Создать элемент <img>
img.src = getBlobURL(files[i]); // URL blob:
// в <img>
img.onload = function() { // После загрузки изобр.
this.width = 100; // установить его размеры
document.body.appendChild(this); // и вставить в документ.
revokeBlobURL(this.src); // Предотвратить утечки памяти!
}
}
droptarget.classList.remove("active"); //Снять выделение
return false; // Событие сброса обработано
}
};
</script>
<style> /* Простые стили для оформления площадки сброса */
#droptarget { border: solid black 2px; width: 200px; height: 200px; }
#droptarget.active { border: solid red 4px; }
</style>
</head>
<body> <!-- Изначально в документе имеется только площадка сброса -->
<div>C6pocbTe сюда файлы изображений</div>
</body>
</html>
URL-адреса двоичных объектов имеют то же происхождение (раздел 13.6.2), что и сценарии, создавшие их. Это делает их более универсальными по сравнению с URL-адресами file://, которые имеют иное происхождение, из-за чего последние сложнее использовать в веб-приложениях. URL-адреса двоичных объектов считаются допустимыми только в документах с общим происхождением. Если, например, с помощью метода postMessage()
передать URL-адрес двоичного объекта в окно с документом, имеющим другое происхождение, для этого окна URL-адрес будет бессмысленным.
URL-адреса двоичных объектов не являются постоянными. Такой URL-адрес перестанет быть действительным, как только пользователь закроет документ или выйдет из документа, в котором был создан этот URL-адрес. Нельзя, например, сохранить URL-адрес двоичного объекта в локальном хранилище и затем повторно использовать его, когда пользователь начнет новый сеанс работы с веб-приложением.
Имеется также возможность вручную «прекращать» действие URL-адреса двоичного объекта вызовом метода URL. revokeObjectURL()
(или webkitURL.revokeObjectURL()
), и, как вы могли заметить, пример 22.10 использует эту возможность. Это связано с проблемой управления памятью. После того как миниатюра будет отображена, двоичный объект становится ненужным и его следует сделать доступным для утилизации сборщиком мусора. Но если веб-броузер будет хранить ссылку на созданный двоичный объект в виде URL-адреса двоичного объекта, он не сможет утилизировать его, даже если он не будет больше использоваться в приложении. Интерпретатор JavaScript не может следить за использованием строк, и если URL-адрес по-прежнему остается допустимым, он вправе предположить, что этот адрес все еще используется. Это означает, что интерпретатор не сможет утилизировать двоичный объект, пока не будет прекращено действие URL-адреса. Пример 22.10 работает с локальными файлами, не требующими утилизации, но представьте, какие серьезные утечки памяти могут быть при работе с двоичными объектами, создаваемыми в памяти методом BlobBuilder
или загружаемыми с помощью объекта XMLHttpRequest
и сохраняемыми во временных файлах.
URL-схема blob:// явно проектировалась как упрощенный вариант схемы http://, и при обращении по URL-адресу blob:// броузеры должны действовать как своеобразные HTTP-серверы. При запросе недействительного URL-адреса двоичного объекта броузер должен послать в ответ код состояния 404 «Not Found». При запросе URL-адреса двоичного объекта с другим происхождением броузер должен вернуть код состояния 403 «Not Allowed». URL-адреса двоичных объектов могут использоваться только в запросах GET, и в случае успешного выполнения запроса броузер должен отправить код состояния 200 «ОК» и заголовок Content-Type со значением свойства type двоичного объекта Blob. Поскольку URL-адреса двоичных объектов действуют как упрощенные URL-адреса http://, их содержимое можно «загружать» с помощью объекта XMLHttpRequest
. (Однако, как будет показано в следующем разделе, содержимое двоичного объекта можно прочитать более непосредственным способом - с помощью объекта FileReader
.)
- 22.6. Двоичные объекты
- 22.6.1. Файлы как двоичные объекты
- ЧАСТЬ IV. База данных и ее объекты.
- Физические объекты
- Глава 2 Обнаружение адреса
- 5.21 IP-адреса, интерфейсы и множественное пребывание
- Абстрактные базы как двоичные интерфейсы
- Объекты без прототипов
- Spurl
- 3.6.1. Адресация в Linux
- 4.12.2. Переадресация
- Объекты базы данных