Pull to refresh

Ломаем web c '#!' (hash-bang)

Reading time 6 min
Views 18K
Original author: Mike Davies
Ниже предлагается перевод статьи, обращающей внимание на, на мой взгляд, довольно острую проблему в эпоху web 2.0, а именно чистоту URL-адресов.

На примере сайта Lifehacker.com показано какими проблемами может обернуться слепое следование state-of-the-art технологиям, погоней за SEO и отрицание принципа «прогрессивного улучшения» (progressive enhancement).


На прошлой неделе, в понедельник, сайт Lifehacker.com был недоступен по причине неработающего JavaScript. Lifehacker.com, наряду с остальными сайтами компании Gawker, отображали пустую главную страницу без контента, рекламы и всего остального. Переход с результатов поиска Google на подстраницы переправлял обратно на главную.

Javascript-зависимые URL


Gawker, как и Twitter до него, перестроил свои сайты на полную зависимость от JavaScript'а, включая URLы его страниц. JavaScript не смог загрузиться, что привело к отсутствию контента и сломаным URLам.

Новые адреса страниц выглядят теперь следущим образом: http://lifehacker.com/#!5753509/hello-world-this-is-the-new-lifehacker. До понедельника, адрес был тем же, только без #!..

Идентификаторы фрагментов


# — это специальный символ URL, который сообщает браузеру, что последующая часть адреса представляет собой ссылку на HTML элемент с таким id или именованый якорь (named anchor) текущей страницы. В случае lifehacker.com, текущая страница — это главная страница.

Получается, что до понедельника сайт состоял из миллиона страниц, а теперь это 1 страница с миллионом идентификаторов фрагментов.

Зачем? Я не знаю. Twitter ответил на этот вопрос, когда перешел на такую же технологию, что Google так сможет проиндекировать твиты. Это так, но того же можно было достичь и с предыдущей правильной структурой адреса, с меньшими затратами.

Решение проблемы

Синтакс адреса с #! (hash-bang) впервые вышел на арену web-разработки, когда Google анонсировал способ для веб-разработчика сделать сайт доступным для индексации роботом.

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

Гугл потратил много времени, чтобы решить эту проблему, не преуспел в этом и решил зайти с другого конца. Вместо попыток отыскать этот мифический контент, пусть владельцы сайта сами сообщат о нем. Для этого была разработана спецификация.

Надо отдать должное, что Google аккуратно сакцентировал внимание разработчиков, о том, что они должны делать сайты с «прогрессивным улучшением» (progressive eтhancement) и не полагаться на JavaScript в рамках контента:

If you’re starting from scratch, one good approach is to build your site’s structure and navigation using only HTML. Then, once you have the site’s pages, links, and content in place, you can spice up the appearance and interface with Ajax. Googlebot will be happy looking at the HTML, while users with modern browsers can enjoy your Ajax bonuses.


Т.е. синтаксис адресов с #! был специально разработан для сайтов кладущих с прибором на фундаментальный принцип веб-разработки, и дал таким сайтом глоток жизни, чтобы их контент был обнаружен ботом.

И теперь, этот спасательный круг, похоже, принимается как Единственный Верный Путь веб-разработки инженерами Facebook, Twitter и теперь Lifehacker.com

Чистые URLы

В спецификации Google, #!-адреса называются как «prettyURLs», и они трансформируются ботом в нечто более гротескное.

В прошлое воскресенье, адрес Lifehacker'а выглядил например так: http://lifehacker.com/5753509/hello-world-this-is-the-new-lifehacker.

Хорошо. 7-значный код в середине — единственный непонятный фрагмент, но он требуется CMSкой для однозначного определения статьи. Поэтому, это практически «чистый» адрес.

Сегодня, таже самая статья доступна по адресу: http://lifehacker.com/#!5753509/hello-world-this-is-the-new-lifehacker.Теперь адресс менее «чист», чем предыдущий, так как добавление #! фундаментально меняет структуру адреса:
  • Адрес /5753509/hello-world-this-is-the-new-lifehacker становится просто /
  • Добавлен новый идентификатор фрагмента !5753509/hello-world-this-is-the-new-lifehacker добавляется к адресу.
Достигли мы чего-либо? Нет. Но коверкание адреса на этом не заканчивается.

Спецификация Гугла говорит о том, что адрес будет переделан в адрес с параметрами, т.е. в: http://lifehacker.com/?_escaped_fragment_=5753509/hello-world-this-is-the-new-lifehacker.

Таким образом, именно этот адрес возвращает контент, т.е. этот адрес является каноническим (canonical), т.е. то что будет индексировать бот.

Похоже на: http://example.com/default.asp?page=about_us

Lifehacker.com вместе с Gawker просто забили на 10-летний опыт по чистым адресам и пришли обратно к типичному ASP-сайту (Сколько еще достанется от Frontpage'а?).

В чем проблема?

Основная проблема, что адреса Lifehacker.com не указывают на контент. Каждый URL указывает на главную страницу. Если вам повезло и с JavaScript'ом у вас все хорошо, на главную страницу положится нужный контент.

Более заковыристый по сравнению с обычным адрес, более подверженный ошибкам и более хрупкий подход.

Получается, что запрашивая адрес привязанный к контенту, инициатор запроса контент не получает. Т.е. поломка заложена в конструкции. Lifehacker.com умышленно не дает ботам ходить по ссылкам за интересным контентом. Конечно, если не прыгать через обруч придуманный Гуглом.

Так и зачем нужен этот обруч?

Назначение #!

Так и зачем использовать #!-адреса если этот синтетический адрес, который должен быть еще и переделан в другой, который будет непосредственно отдавать контент?
Из всех причин, самая сильная — «Потому что так круто!». Я сказал самая сильная, а не сильная.

Инженеры будут бурчать что-то про сохранение состояния в Ajax-приложениях. И честно говоря, это идиотская причина для ломания адреса таким способом. Адрес в аттрибуте href все равно может быть нормально сформированной ссылкой на контент. Так как вы все равно используете JavaScript, испортить ее можно позже, в своем обработчике клика по ссылке, добавив в нужное место #!.. Так получится, что поддержание состояния есть, и без ненужного закрытия сайта от ботов и вообще всего не-Javascript'ового.

Запретить всех ботов (кроме Гуглбота)

Все небраузерные агенты (пауки, аггрегаторы, индексирующие сканеры), которые полностью поддерживают как HTTP/1.1 и спецификацию URL (RFC-2396, например) не смогу пройтись по Lifehacker.com, конечно, кроме Гуглбота.

Таким образом надо рассмотреть следующие последствия:
  1. Кэширование больше не работает, так как промежуточные серверы не имеют канонического представления контента и соотвественно не кэшируют ничего. Это приводит к тому, что Lifehacker открывается дольше, Gawker несет бОльшие убытки из-за увеличенного трафика.
  2. HTTP/1.1 и RFC-2396 совместимые краулеры не увидят ничего кроме пустой домашней страницы. Т.е. приложения и сервисы, которые построены на таких краулерах получают соответствующий эффект.
  3. Потенциальное использование микроформатов значительно сокращается, т.е. только браузерные и Гугловые аггрегаторы смогут увидеть микроформатные данные.
  4. Facebook Like виджеты, которые используют идентификаторы страниц потребуют дополнительных действий, чтобы страница была Like'нута (по умолчанию, так как главная страница единственная, на которую указывают прямые URLы, а все «кривые» с #! будут пониматься как ссылка опять же на главную).

Зависимость от идеального JavaScript

Если контент не может быть получен по URL, получается, что сайт сломан. Gawker осознанно пошли на этот шаг с ломанием ссылок. Они оставили доступность своего сайта на откуп всяким JavaScript -ошибкам.
  • Невозможность загрузить JS привела к 5 часовой недоступности всех сервисов Gawker'а в прошлый понедельник (07/02/2011).
  • Отстуствие точки с запятой (;) в конце объекта или массива, объявленного литералом, вызовет ошибку в Internet Explorer'е.
  • Случайно оставленная console.log() опять же вызовет падения у пользователя невооруженного девелоперскими тулами.
  • Рекламные вставки постоянно оказываются с ошибками. Ошибка в рекламном блоке — нету сайта. А опытные веб-разработчики знают, что самый унылый код как раз в рекламных баннерах.
Такая хрупкость без реальной причины и выгода, не перевешивающая все недостатки. Существуют гораздо лучшие методы, чем тот, который применил Lifehacker. Даже HTML5 и его History API были бы лучшим решением.

Кошмар архитектуры

Gawker/Lifehacker нарушили принцип «постепенного улучшения» и поплатились за это сразу же падением их стайта в день запуска. Каждый промах в JavaScript будет приводить к падению и прямо сказываться на доходах Gawker и доверии их аудитории.

Дополнительная литература
  • http://www.tbray.org/ongoing/When/201x/2011/02/09/Hash-Blecch
  • http://blog.benward.me/post/3231388630
Tags:
Hubs:
+114
Comments 109
Comments Comments 109

Articles