URL'ы не должны были стать тем, чем стали: мудрёным способом идентифицировать сайт в интернете для пользователя. К сожалению, мы не смогли стандартизировать URN, который мог бы стать более полезной системой наименования. Считать, что современная система URL достаточно хороша — это как боготворить командную строку DOS и говорить, что все люди просто должны научиться пользоваться командной строкой. Оконные интерфейсы были придуманы, чтобы пользоваться компьютерами стало проще, и чтобы сделать их популярнее. Такие же мысли должны привести нас к более хорошему методу определения сайтов в Вебе.
— Дейл Догэрти,
1996
Есть несколько вариантов определения слова "интернет". Один из них — это система компьютеров, соединенных через компьютерную сеть. Такая версия интернета появилась в 1969 году с созданием ARPANET. Почта, файлы и чат работали в этой сети еще до создания HTTP, HTML и веб-браузера.
В 1992 году Тим Бернерс-Ли создал три штуки, благодаря которым родилось то, что мы считаем интернетом: протокол HTTP, HTML и URL. Его целью было воплотить понятие гипертекста в реальности. Гипертекст, в двух словах — это возможность создавать документы, которые ссылаются друг на друга. В те годы идея гипертекста считалась панацеей из научной фантастики, заодно с гипермедиа, и любыми другими словами с приставкой «гипер».
Ключевым требованием гипертекста была возможность ссылаться из одного документа на другой. В то время для хранения документов использовалась куча форматов, а доступ осуществлялся по протоколу вроде Gopher или FTP. Тиму нужен был надежный способ ссылаться на файл, так, чтобы в ссылке был закодирован протокол, хост в интернете и местонахождение на этом хосте. Этим способом стал URL, впервые официально задокументированный в RFC в 1994 году.
В начальной презентации World-Wide Web в марте 1992 Тим Бернерс-Ли описал его как «универсальный идентификатор документов» (Universal Document Identifier или UDI). Множество других форматов также рассматривались в качестве такого идентификатора:
protocol: aftp host: xxx.yyy.edu path: /pub/doc/README
PR=aftp; H=xx.yy.edu; PA=/pub/doc/README;
PR:aftp/xx.yy.edu/pub/doc/README
/aftp/xx.yy.edu/pub/doc/README)
Этот документ также объясняет, почему пробелы должны кодироваться в URL (%20):
В UDI избегают использование пробелов: пробелы — это запрещенные символы. Это сделано потому, что часто появляются лишние пробелы когда строки оборачиваются системами вроде mail, или из-за обычной необходимости выровнять ширину колонки, а так же из-за преобразования различных видов пробелов во время конвертации кодов символов и при передаче текста от приложения к приложению.
Важно понимать, что URL был просто сокращенным способом обратиться к комбинации схемы, домена, порта, учетных данных и пути, которые ранее нужно было определять из контекста для каждой из систем коммуникации.
scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]
Эта позволило обращаться к разным системам из гипертекста, но сегодня, возможно, такая форма уже избыточна, так как практически все передается через HTTP. В 1996 браузеры уже добавляли http://
и www.
за пользователей автоматически (что делает рекламу с этими кусками URL по-настоящему бессмысленной).
Путь
Я не считаю, что вопрос «могут ли люди понять значение URL» имеет смысл. Я просто думаю, что морально неприемлемо заставлять бабушку или дедушку вникать в то, что в конечном итоге является нормами файловой системы UNIX.
— Исраэль дель Рио,
1996
Слэш, отделяющий путь в URL, знаком любому, кто использовал компьютер за последние пятьдесят лет. Сама иерархическая файловая система была представлена в системе MULTICS. Ее создатель в свою очередь ссылается на двухчасовую беседу с Альбертом Эйнштейном, которая состоялась в 1952 году.
В MULTICS использовался символ «больше» (>
) для разделения компонентов файлового пути. Например:
>usr>bin>local>awk
Это совершенно логично, но, к сожалению, ребята из Unix решили использовать >
для обозначения перенаправления, а для разделения пути взяли слэш (/
).
Битые ссылки в решениях Верховного Суда
Неправильно. Теперь я четко вижу, что мы не согласны друг с другом. Вы и я.
…
Как человек, я хочу сохранить за собой право использовать разные критерии для разных целей. Я хочу иметь возможность давать имена самим работам, и конкретным переводам и конкретным версиям. Я хочу более богатого мира чем тот, что вы предлагаете. Я не хочу ограничивать себя вашей двухуровневой системой «документов» и «вариантов».
— Тим Бернерс-Ли,
1993
Половины URL-адресов, на которые ссылается Верховный Суд США, уже не существует. Если вы читаете академическую работу в 2011 году, и написана она была в 2001 году, то с большой вероятностью любой URL там будет нерабочим.
В 1993 году многие страстно верили, что URL отомрет, и на замену ему придет URN. Uniform Resource Name — это постоянная ссылка на любой фрагмент, который, в отличие от URL, никогда не изменится и не сломается. Тим Бернерс-Ли описал его как «срочную необходимость» еще в 1991.
Простейший способ создать URN — это использовать криптографический хэш содержания страницы, например:urn:791f0de3cfffc6ec7a0aacda2b147839
. Однако, этот метод не удовлетворяет критериям веб-сообщества, так как невозможно выяснить, кто и как будет конвертировать этот хэш обратно в реальный контент. Такой способ также не учитывает изменений формата, которые часто происходят в файле (например, сжатие файла), которые не влияют на содержание.
В 1996 Киф Шэйфер и несколько других специалистов предложили решение проблемы поломанных URL. Ссылка на это решение сейчас не работает. Рой Филдинг опубликовал предложение реализации в июле 1995 года. Ссылка тоже поломана.
Я смог найти эти страницы через Google, который по сути сделал заголовки страниц современным аналогом URN. Формат URN был окончательно оформлен в 1997 году, и практически не использовался с тех пор. У него интересная реализация. Каждый URN состоит из двух частей: authority
, который может преобразовать определенный тип URN, и конкретный идентификатор документа в понятном для authority
формате. Например, urn:isbn:0131103628
будет обозначать книгу, формируя постоянную ссылку, которая (надеюсь) будет конвертирована в набор URL'ов вашим локальным преобразователем isbn
.
Учитывая мощность поисковых движков, возможно, что лучшим на сегодня форматом URN могла бы стать простая возможность файлов ссылаться на свой прошлый URL. Мы можем позволить поисковым движкам индексировать эту информацию, и ссылаться на наши страницы корректно:
<!-- On http://zack.is/history -->
<link rel="past-url" href="http://zackbloom.com/history.html">
<link rel="past-url" href="http://zack.is/history.html">
Параметры запроса
Формат application/x-www-form-urlencoded — это аномальный монстр во многих отношениях, результат многих лет случайностей реализаций и компромиссов, которые привели к необходимому для интероперабельности набору требований. Но это точно не образец хорошей архитектуры.
Если вы использовали веб какое-то время, то вам знакомы параметры запросов. Они находятся после пути и нужны для кодирования параметров вроде ?name=zack&state=mi
. Может показаться странным, что запросы используют символ амперсанда (&
), который в HTML используется для кодирования специальных символов. Если вы писали на HTML, то скорее всего столкнулись с необходимостью кодировать амперсанды в URL, превращая http://host/?x=1&y=2
в http://host/?x=1&y=2
или http://host?x=1&y=2
(конкретно эта путаница существовала всегда).
Возможно, вы также замечали, что куки (cookies) используют похожий, но все же иной формат: x=1;y=2
, и он никак не конфликтует с символами HTML. W3C не забыл про эту идею и рекомендовал всем поддерживать как ;
, так и &
в параметрах запросов еще в 1995 году.
Изначально эта часть URL использовалась исключительно для поиска индексов. Веб изначально был создан (и его финансирование было основано на этом) как метод совместной работы физиков, занимающихся элементарными частицами. Это не означает, что Тим Бернерс-Ли не знал, что он создает систему коммуникации с по-настоящему широким применением. Он не добавлял поддержку таблиц несколько лет, не смотря на то, что таблицы, наверное, пригодились бы физикам.
Так или иначе, физикам нужен был способ кодирования и связывания информации, и способ поиска этой информации. Для этого Тим Бернерс-Ли создал тег <ISINDEX>
. Если <ISINDEX>
присутствовал на странице, то браузер знал, что по этой странице можно делать поиск. Браузер показывал поисковую строку и позволял пользователю делать запрос на сервер.
Запрос представлял собой набор ключевых слов, отделенных друг от друга плюсами (+
):
http://cernvm/FIND/?sgml+cms
Как это обычно случается в интернете, тег стали использовать для всего подряд, в том числе как поле ввода числа для вычисления квадратного корня. Вскоре предложили принять тот факт, что такое поле слишком специфично, и нужен тег общего характера <input>
.
В том предложении использовался символ плюса для отделения компонентов запроса, но в остальном все напоминает современный GET-запрос:
http://somehost.somewhere/some/path?x=xxxx+y=yyyy+z=zzzz
Далеко не все одобрили это. Некоторые считали, что нужен способ указать поддержку поиска по ту сторону ссылки:
<a HREF="wais://quake.think.com/INFO" INDEX=1>search</a>
Тим Бернерс-Ли думал, что нужен способ определения строго типизированных запросов:
<ISINDEX TYPE="iana:/www/classes/query/personalinfo">
Изучая прошлое, готов с определенной долей уверенности сказать: я рад, что победило более общее решение.
Работа над тегом <INPUT>
началась в январе 1993 года, она основывалась на более старом типе SGML. Было решено (пожалуй, к сожалению), что тегу <SELECT>
нужна своя, более широкая структура:
<select name=FIELDNAME type=CHOICETYPE [value=VALUE] [help=HELPUDI]>
<choice>item 1
<choice>item 2
<choice>item 3
</select>
Если вам любопытно, то да, была идея повторно использовать элемент <li>
вместо создания нового <option>
. Однако, были и другие предложения. В одном из них происходила замена переменных, что напоминает современный Angular:
<ENTRYBLANK TYPE=int LENGTH=length DEFAULT=default VAR=lval>
Prompt </ENTRYBLANK>
<QUESTION TYPE=float DEFAULT=default VAR=lval> Prompt </QUESTION>
<CHOICE DEFAULT=default VAR=lval>
<ALTERNATIVE VAL=value1> Prompt1
...
<ALTERNATIVE VAL=valuen> Promptn
</CHOICE>
В этом примере проверяется тип input'ов на основе указания type
, а значения VAR
доступны на странице для замены строк в URL, примерно так:
http://eager.io/apps/$appId
Дополнительные предложения использовали @
вместо =
для разделения компонентов запроса:
name@value+name@(value&value)
Марк Андриссен предложил метод, основанный на том, что он уже реализовал в Mosaic:
name=value&name=value&name=value
Всего два месяца спустя Mosaic добавил поддержку method=POST
в формы, и так родились современные HTML-формы.
Конечно, компания Netscape Марка Андриссена создала еще и формат куки (с другим разделителем). Их предложение было болезненно недальновидным, оно привело к попытке создания заголовка Set-Cookie2
, и создало фундаментальные структурные проблемы, с которыми нам все еще приходится иметь дело в продукте Eager.
Фрагменты
Часть URL после символа ‘#’ известна как «фрагмент» (fragment). Фрагменты были частью URL со времен первой спецификации, они использовались для создания ссылки на конкретное место на загруженной странице. Например, если у меня есть якорь на сайте:
<a name="bio"></a>
Я могу сделать на него ссылку:
http://zack.is/#bio
Эта концепция постепенно была расширена до всех элементов (а не только якорей), и перешла на атрибут id
вместо name
:
<h1 id="bio">Bio</h1>
Тим Бернерс-Ли решил использовать этот символ, основываясь на связи с форматом почтовых адресов в США (не смотря на то, что сам Тим — британец). По его словам:
Как минимум в США в почтовых адресах часто используют знак номера для указания номера квартиры или комнаты в здании. 12 Acacia Av #12 означает «Здание 12 на Акация Авеню, и в этом здании квартира 12». Этот символ казался естественным для такой цели. Сегодня http://www.example.com/foo#bar означает «На ресурсе http://www.example.com/foo конкретный вид, известный как bar”.
Оказывается, первичная система гипертекста, созданная Дугласом Энгельбартом, также использовала "#" для таких целей. Это может быть совпадением или случайным «заимствованием идеи».
Фрагменты специально не включаются в HTTP-запросы, то есть они живут исключительно в браузере. Такая концепция оказалась ценной, когда пришло время реализовывать клиентскую навигацию (до изобретения pushState). Фрагменты также были очень полезными, когда пришло время задуматься о сохранении состояния в URL без отправки на сервер. Что это значит? Давайте разберемся:
Кротовые холмики и горы
Есть целый стандарт, такой же мерзкий как SGML, созданный для передачи электронных данных, другими словами — для форм и отправки форм. Единственное, что мне известно: он выглядит как фортран задом наперед без пробелов.
— Тим Бернерс-Ли,
1993
Есть ощущение, разделяемое многими, что организации, отвечающие за стандарты интернета ничего особо не делали с момента окончательного принятия HTTP 1.1. и HTML 4.01 в 2002 до тех пор, пока HTML 5 не стал по-настоящему популярным. Этот период также известен (только для меня) как Темный Век XHTML. В реальности люди, занимающиеся стандартами, были безумно заняты. Просто они занимались тем, что в итоге оказалось не слишком ценным.
Одним из направлений было создание Семантического Веба. Была мечта: создать Фреймворк Описания Ресурсов (Resource Description Framework). (прим. ред.: бегите от любой команды, которая хочет сделать фреймворк). Такой фреймворк позволял бы универсально описывать мета-информацию о содержании. Например, вместо того, чтобы делать красивую веб-страницу про мой Корвет Стингрэй, я бы сделал RDF-документ с описанием размеров, цвета и количества штрафов за превышение скорости, которые мне выписали за все время езды.
Это, конечно, совсем не плохая идея. Но формат был основан на XML, и это большая проблема курицы и яйца: нужно задокументировать весь мир, и нужны браузеры, которые умеют делать полезные штуки с этой документацией.
Но эта идея хотя бы родила условия для философских споров. Один из лучших подобных споров длился как минимум десять лет, он известен под искусным кодовым именем ‘httpRange-14’.
Целью httpRange-14 было ответить на фундаментальный вопрос «чем является URL?». Всегда ли URL ссылается на документ или он может ссылаться на все, что угодно? Может ли URL ссылаться на мою машину?
Они не пытались ответить на этот вопрос хоть сколько-нибудь удовлетворительно. Вместо этого они фокусировались на том, как и когда можно использовать редирект 303 чтобы сообщить пользователю, что по ссылке нет документа, и перенаправить его туда, где документ есть. И на том, когда можно использовать фрагменты (часть после ‘#’), чтобы направлять пользователей на связанные данные.
Прагматичному современному человеку эти вопросы могут показаться смешными. Многие из нас привыкли, что если URL получается использовать для чего-то, то значит его можно использовать для этого. И люди или будут использовать ваш продукт, или нет.
Но Семантический Веб заботился только о семантике.
Эта конкретная тема обсуждалась 1 июля 2002 года, 15 июля 2002 года, 22 июля 2002 года, 29 июля 2002 года, 16 сентября 2002 года, и как минимум еще 20 раз в течение 2005 года. Обсуждение закончилось благодаря тому самому ‘решению httpRange-14’ в 2005 году, и к нему вернулись снова из-за жалоб в 2007 и 2011, а запрос новых решений был открыт в 2012. Вопрос долго обсуждался группой pedantic web, у которой очень подходящее название. Единственное, чего так и не произошло — никакие из этих семантических данных так и не были добавлены в веб в какой-либо URL.
Авторизация
Как вы знаете, в URL можно включить логин и пароль:
http://zack:shhhhhh@zack.is
Браузер кодирует эти данные в формат Base64 и посылает в виде заголовка:
Authentication: Basic emFjazpzaGhoaGho
Base64 используется только для того, чтобы можно было передавать запрещенные в заголовках символы. Он никак не скрывает логин и пароль.
Это было проблемой, особенно до распространения SSL. Любой человек, который следит за вашим соединением, мог с легкостью увидеть пароль. Предлагали много альтернатив, в том числе Kerberos, который был и остается популярным протоколом безопасности.
Как и с другими примерами нашей истории, простую базовую авторизацию было проще всего реализовать разработчикам браузеров (Mosaic). Так базовая авторизация стала первым и единственным решением до тех пор, пока разработчики не получили инструменты для создания собственных систем аутентификации.
Веб-приложение
В мире веб-приложений странно представить, что основой веба является гиперссылка. Это метод соединения одного документа с другим, который со временем оброс стилями, возможностью запуска кода, сессиями, аутентификацией и в конечном итоге стал общей социальной компьютерной системой, которую пытались (безуспешно) создать так много исследователей 70-х годов.
Вывод такой же, как и у любого современного проекта или стартапа: только распространение имеет смысл. Если вы сделали что-то, что люди используют, даже если это некачественный продукт, то они помогут вам превратить его в то, чего хотят сами. И с другой стороны, конечно, если никто не пользуется продуктом, то его техническое совершенство не имеет значения. Существует бесчисленное количество инструментов, на которые ушли миллионы часов работы, но ими пользуется ровно ноль человек.
Автор: freetonik