Summary

  • 17 ноября 2009 года W3C опубликовал первый открытый рабочий проект File API: список выбранных файлов FileList и чтение их содержимого через FileReader.
  • Проекты 2013 и 2015 годов уточнили Blob, асинхронное чтение и blob-адреса. Просмотр выбранного файла в браузере и передача на сервер оставались разными этапами.

В фотоателье посетитель кладёт на стойку одну фотографию. Сотрудник должен рассмотреть её и спросить, нужна ли печать. Если вместо этого он начнёт рыться в домашнем архиве клиента, спор о размере отпечатка быстро закончится. У веб-страницы была похожая техническая задача: получить именно тот местный файл, который указал человек, и иметь возможность с ним работать. Ключ от всего шкафа для этого не требовался.

Первый открытый рабочий проект File API от 17 ноября 2009 года начинался с индивидуально выбранных файлов. Поле <input type="file"> могло открыть диалог выбора, FileList описывал его результат. Объект File содержал имя и тип, Blob представлял сырые байты и их фрагменты. FileReader читал данные и сообщал о ходе работы через события. Страница получала пригодный для программы предмет, а не право составить опись соседних папок.

Форма загрузки и раньше могла послать файл серверу. Новизна состояла в том, что страница могла разобраться с ним до отправки. В проекте 2009 года перечислялись асинхронные методы readAsBinaryString, readAsText и readAsDataURL. Выбранный снимок можно было показать, текст — прочитать. Ошибочную фотографию человек замечал до того, как её копия отправлялась через сеть. Кнопка выбора становилась началом работы, а не только первым шагом почтовой службы.

Примеры в проекте показывали и другие задачи. Просмотрщик текстов песен мог открыть выбранный плейлист и разложить записи по порядку внутри страницы. Календарное приложение могло прочитать локальный календарь, совместить события и затем предложить синхронизацию. Файл в этих сценариях был материалом для приложения. Наличие материала на рабочем столе браузера ещё не означало, что он уже лежит на сервере.

Потому момент выбора был главным. В разделе о безопасности проект 2009 года исходил из того, что файлы для FileReader сначала выбирает пользователь. Авторы обсуждали навязчивый диалог, который снова и снова требует указать файл, чувствительные системные файлы и изменение содержимого на диске между выбором и чтением. Локальный файл не похож на неподвижную строку в странице: другая программа может его изменить, а браузер может отказаться читать опасный объект. Стойка фотоателье стоит посреди живого города, а не в стерильной лаборатории.

Проект Last Call от 12 сентября 2013 года лучше распределил роли. FileList содержал выбранные объекты; неизменяемый Blob держал данные и позволял выделять фрагменты; File добавлял имя и сведения о времени изменения. FileReader читал асинхронно, посылая сообщения о ходе, завершении и ошибке. В примере выбранный файл читали как текст, а страница обновляла индикатор. При медленном диске пользователю можно было показать, что работа продолжается, вместо молчаливого зависания.

Затем возникла привычная для веба проблема: изображение на странице любит URL, а выбранное фото существует как локальный объект. Проекты предложили blob-адреса для такой ссылки. Рабочий проект от 21 апреля 2015 года показывал, как URL.createObjectURL() помогает вывести предварительный просмотр, а URL.revokeObjectURL() прекращает действие ссылки после использования. В документе отмечалось, что забытые ссылки могут задерживаться. Номерок, выданный на стойке, полезен, пока работа идёт; после неё номерок надо убрать.

В 2015 году уточнялась и одна маленькая граница. File.name возвращал имя файла без пути к папкам выше него. Странице достаточно подписать превью «снимок.jpg». Ей незачем знать всю схему личного архива. Тот же проект связывал blob-адреса с происхождением страницы и предусматривал ошибку для запроса из другого происхождения. Полезность выбранного файла создавали байты и понятный интерфейс, а не подробный план чужого диска.

Официальная история публикаций W3C фиксирует первый открытый проект в 2009 году, Last Call в 2013-м и очередной рабочий проект в 2015-м. Это не рассказ о волшебном дне, когда сайты внезапно научились правильно обращаться со всеми файлами. Несколько лет уточнялось гораздо более скромное соглашение: выбранный человеком объект можно одинаково представить и прочитать в разных веб-приложениях.

Дальше решения принимает само приложение. Оно может показать снимок в странице, изменить его или передать байты на сервер другими средствами. Превью само по себе не доказывает отправку, а выбор файла не объясняет судьбу будущих копий. Но точная первая передача позволяет задать эти вопросы без путаницы. Пользователь видит, какой предмет оказался на стойке и когда его собираются унести.

Неверную фотографию теперь можно заменить до загрузки. Календарь можно проверить до синхронизации. Большой документ может показывать прогресс. У этой истории нет громкого финала с ленточкой и оркестром. Есть сотрудник, который умеет работать с одним снимком, и шкаф, оставшийся у хозяина дома.