<b><style> /* Простые стили для оформления площадки сброса */</b>
<b> #droptarget { border: solid black 2px; width: 200px; height: 200px; }</b>
<b> #droptarget.active { border: solid red 4px; }</b>
<b></style></b>
<b></head></b>
<b><body> <!-- Изначально в документе имеется только площадка сброса --></b>
<b> <div id="droptarget">C6pocbTe сюда файлы изображений</div></b>
<b></body></b>
<b></html></b>
URL-адреса двоичных объектов имеют то же происхождение (раздел 13.6.2), что и сценарии, создавшие их. Это делает их более универсальными по сравнению с URL-адресами file://, которые имеют иное происхождение, из-за чего последние сложнее использовать в веб-приложениях. URL-адреса двоичных объектов считаются допустимыми только в документах с общим происхождением. Если, например, с помощью метода
<b>postMessage()</b>
передать URL-адрес двоичного объекта в окно с документом, имеющим другое происхождение, для этого окна URL-адрес будет бессмысленным.
URL-адреса двоичных объектов не являются постоянными. Такой URL-адрес перестанет быть действительным, как только пользователь закроет документ или выйдет из документа, в котором был создан этот URL-адрес. Нельзя, например, сохранить URL-адрес двоичного объекта в локальном хранилище и затем повторно использовать его, когда пользователь начнет новый сеанс работы с веб-приложением.
Имеется также возможность вручную «прекращать» действие URL-адреса двоичного объекта вызовом метода URL.
<b>revokeObjectURL()</b>
(или
<b>webkitURL.revokeObjectURL()</b>
), и, как вы могли заметить, пример 22.10 использует эту возможность. Это связано с проблемой управления памятью. После того как миниатюра будет отображена, двоичный объект становится ненужным и его следует сделать доступным для утилизации сборщиком мусора. Но если веб-броузер будет хранить ссылку на созданный двоичный объект в виде URL-адреса двоичного объекта, он не сможет утилизировать его, даже если он не будет больше использоваться в приложении. Интерпретатор JavaScript не может следить за использованием строк, и если URL-адрес по-прежнему остается допустимым, он вправе предположить, что этот адрес все еще используется. Это означает, что интерпретатор не сможет утилизировать двоичный объект, пока не будет прекращено действие URL-адреса. Пример 22.10 работает с локальными файлами, не требующими утилизации, но представьте, какие серьезные утечки памяти могут быть при работе с двоичными объектами, создаваемыми в памяти методом
<b>BlobBuilder</b>
или загружаемыми с помощью объекта
<b>XMLHttpRequest</b>
и сохраняемыми во временных файлах.
URL-схема blob:// явно проектировалась как упрощенный вариант схемы http://, и при обращении по URL-адресу blob:// броузеры должны действовать как своеобразные HTTP-серверы. При запросе недействительного URL-адреса двоичного объекта броузер должен послать в ответ код состояния 404 «Not Found». При запросе URL-адреса двоичного объекта с другим происхождением броузер должен вернуть код состояния 403 «Not Allowed». URL-адреса двоичных объектов могут использоваться только в запросах GET, и в случае успешного выполнения запроса броузер должен отправить код состояния 200 «ОК» и заголовок Content-Type со значением свойства type двоичного объекта Blob. Поскольку URL-адреса двоичных объектов действуют как упрощенные URL-адреса http://, их содержимое можно «загружать» с помощью объекта
<b>XMLHttpRequest</b>
. (Однако, как будет показано в следующем разделе, содержимое двоичного объекта можно прочитать более непосредственным способом - с помощью объекта
<b>FileReader</b>
.)
22.6.5. Чтение двоичных объектов
До сих пор двоичные объекты были для нас непрозрачными фрагментами данных, которые позволяют обращаться к их содержимому только косвенным способом, посредством URL-адресов двоичных объектов. Объект
<b>FileReader</b>
дает возможность читать символы или байты, хранящиеся в двоичном объекте, и его можно рассматривать как противоположность объекту
<b>BlobBuilder</b>
. (Для него больше подошло бы имя
<b>BlobReader</b>
, поскольку он может работать с любыми двоичными объектами, а не только с файлами.) Так как двоичные объекты могут быть очень большими и храниться в файловой системе, прикладной интерфейс чтения их содержимого действует асинхронно, во многом подобно тому, как действует объект
<b>XMLHttpRequest</b>
. Фоновым потокам доступна также синхронная версия прикладного интерфейса в виде объекта
<b>FileReaderSync</b>
, хотя они могут использовать и асинхронную версию.
Чтобы воспользоваться объектом
<b>FileReader</b>
, сначала необходимо создать его экземпляр с помощью конструктора
<b>FileReader().</b>
Затем определить обработчики событий. Обычно в приложениях определяются обработчики событий «load» и «error» и иногда - обработчик событий «progress». Сделать это можно посредством свойств
<b>onload, onerror</b>
и
<b>onprogress</b>
или с помощью стандартного метода
<b>addEventListener().</b>
Кроме того, объекты
<b>FileReader</b>
генерируют события «loadstart», «loadend» и «abort», которые соответствуют одноименным событиям в объекте
<b>XMLHttpRequest</b>
(раздел 18.1.4).
После создания объекта
<b>FileReader</b>
и регистрации необходимых обработчиков событий можно передать двоичный объект, содержимое которого требуется прочитать, одному из четырех методов:
<b>readAsText(), readAsArrayBuffer(), readAsDataURL()</b>
и
<b>readAsBinaryString().</b>
(Разумеется, можно сначала вызвать один из этих методов и лишь потом зарегистрировать обработчики событий - благодаря однопоточной природе JavaScript, о которой рассказывалось в разделе 22.4, обработчики событий не могут быть вызваны, пока ваша функция не вернет управление и броузер не сможет продолжить цикл обработки событий.) Первые два метода являются наиболее важными, и только они будут описаны здесь. Каждый из этих методов чтения принимает двоичный объект
<b>Blob</b>
в первом аргументе. Метод
<b>readAsText()</b>
принимает необязательный второй аргумент, определяющий имя кодировки текста. Если кодировка не указана, метод автоматически будет обрабатывать текст в кодировках ASCII и UTF-8 (а также текст в кодировке UTF-16 с маркером порядка следования байтов (byte-order mark, BOM)).