Как стать автором
Обновить

<base> вреден.

Время на прочтение 7 мин
Количество просмотров 1.4K
Тэг <base>, с помощью которого браузеру задают базовый путь для разрешения относительных ссылок, вреден и не должен использоваться в хорошей верстке. Вместо него есть достаточно строгий и гибкий метод задания путей к ресурсам.
Вследствие распространившейся моды на ЧПУ веб-технологи стали чаще встречаться со следующей проблемой — файлы (например, CSS или изображения), на сервере расположенные буквально в соседней папке с шаблонами верстки, теперь не получается адресовать относительными путями. При автоматическом создании страниц на очень разветвленных сайтах нет практически никакой возможности автоматически изменять относительные пути к ресурсам в зависимости от адреса просматриваемой старницы, и обычные относительные пути перестают работать.

О чем это он?


Браузер, просматривающий адрес example.com/blog/record1, попытается разрешить ссылку ../css/blog.css в адрес example.com/blog/css/blog.css. Возможно, это еще не так плохо, но в ситуации, когда адрес будет каким-нибудь наподобие example.com/blog/tags/test, та же ссылка разрешится в example.com/blog/tags/css/blog.css. Очевидно, хотя присутсвие одного и того же файла по нескольким URL-адресам можно реализовать, делать так явно не стоит. Даже если папка css лежит там же, где и шаблоны верстки, проблема относительной адресации никуда не денется.

Как в таких случаях обычно поступают


Веб-программисты и технологи по всему миру вспомнили в этой нелегкой ситуации о тэге <base>. Согласно спецификации:
Элемент BASE позволяет авторам явно указать базовый URI документа.
Если элемент BASE указан, он должен присутствовать в разделе HEAD документа HTML, до элементов, ссылающихся на внешние ресурсы. Информация о пути, указанная в элементе BASE, влияет только на URI в документе, в котором присутствует этот элемент.

Решение кажется гениально простым: указав в элементе base href="http://example.com/templates/&quot, мы заставим браузер разрешать все вышеуказанные относительные URL в ссылки на реально существующие, лежащие на том самом месте файлы. Избавившись от привычки путешествовать вверх по дереву каталогов в нашем относительном пути, мы избавимся от этих проблем окончательно.

Что не так?


Вот только вкратце список проблем, возникающих при употреблении <base> в таких целях:
  1. Сайт перестает работать с остальных доменов — при попытке просмотра даже www.example.com браузер будет пытаться тянуть ресурсы с example.com (без www). Для CSS и картинок это пока не страшно, но со скриптами (особенно HTC для Internet Explorer), cookies, ActiveX, Flash (если из него подразумевается взаимодействие с сервером), а также в случае обращения по протоколу https у пользователя будут более или менее серьезные проблемы. Подумайте также о сложностях при переносе сайта на другой домен (или употреблении его движка для другого сайта).
  2. <Base> также влияет на относительные адреса употребленные в ссылках, которые теперь тоже разрешаются согласно базовому пути. Даже если указать base href="example.com/", остается коллизия между доменами, указанная в первой проблеме.
  3. Проблема психологического плана: базовый путь, задаваемый в проектах с большой разветвленностью, модульной структурой шаблонов или просто большим объемом кода, может сбить с толку «свежего» верстальщика, незнакомого с проектом, но имеющего задачей вставить пару картинок на страницу.
  4. Самая удивительная проблема: всеми любимый браузер IE, при наличии в просматриваемом документе тэга <base> и элементов разметки с указанным CSS-свойством float (например <div style="float: left;">Тут текст!</div>), не позволит выделять мышью текст в таких элементах. Какая здесь может быть связь — непонятно, но факт.
  5. Тот же IE при разрешении путей, используемых в CSS-фильтрах (например, AlphaImageLoader), игнорирует указание базового пути и пытается разрешать относительные ссылки, как будто никакого <base> не было. Вы не заметите этого, если указываете корень сайта в качестве базового пути, но при любой другой употребленной в этом качестве папке стандартное «лекарство» для PNG работать перестает.

Итак, имеем в итоге: в качестве базового пути лучше употреблять корень сервера, но это создаст некоторые проблемы в IE и серьезные проблемы для работы сайта с несколькими доменами. Решив проблему с относительными путями, мы создали себе еще несколько.
Мне кажется, что в связи с вышеуказанными сложностями от тэга <base> лучше отказаться вовсе. А для решения основной заявленной проблемы воспользоваться другими методами работы с относительными ссылками.

«Полуабсолютная» адресация


Дело в том, что если мы просто будем адресовать ресурсы от корня сервера, начиная путь с символа / («слэш»), то сможем обойтись без <base>, позволяя при этом сайту работать с любого домена и иметь еще некоторые преимущества. Такую адресацию, в противовес обычно применяемой отоносительной, я называю «полуабсолютной» (потому что протокол и домен не указываются, в отличие от настоящей абсолютной адресации).
То есть, файл CSS, указанный в проблемном примере, следует адресовать как /templates/css/blog.css. Такая ссылка будет работать с любым доменом (а также протоколом и портом), так как браузер по умолчанию в качестве базового каталога будет использовать каталог вызываемого документа (то есть, например, example.com/blog/record1 — ведь для браузера этот путь выглядит как каталог, из которого он просматривает индексный документ). Относительные ссылки, начинающиеся со слэша, браузер будет предварять использующимся протоколом и всеми прочими частями URL, заканчивая текущим доменом (и портом, если он указан). Таким образом, проблема адресации ресурсов решается без лишних проблем с доменами.
При этом я призываю к дотошной последовательности: везде, включая конструкции url() и фильтры в CSS и гиперссылки между документами, должна использоваться такая нотация, коль скоро речь идет о работе в пределах одного домена. Это позволит некоторую свободу в обращении с файлами (например, подселить файл CSS в папку images, или отселить в отдельную), сохраняя при этом строгий порядок и работоспособность кода. К несчастью, многие IDE, используемые в веб-разработке, не имеют соотвествующих настроек адресации ресурсов, слишком потакают относительной адресации (особенно с подъемами по дереву каталогов), и даже воспринимают существующие, но указанные «полуабсолютным» методом файлы, как несуществующие ресурсы. Не стоит зависеть от своих инструментов, лучше думать головой.
Однако, и при «полуабсолютной» адресации без проблем не обходится (а вы что думали). В моей практике проблема возникла с Flash — согласно ТЗ, она не просто крутила ролик, а обращалась время от времени к серверу по каким-то своим флэшным делам за одним файлом. Файл флэшка должна была подгружать из «текущего каталога», адресуя его как file.txt. Поскольку использовался движок с ЧПУ, оный каталог был у каждой страницы свой, а стало быть, флэшка не работала.
В тот раз я решил проблему, попросив Flash-технолога адресовать этот файл, как /flash/file.txt. Проблему на сервере это разрешило, однако испортило жизнь самому Flash-технологу (при работе в локальной файловой системе такая адресация разрешается в путь наподобие C:/flash/file.txt). Разумеется, есть решение лучше.

Указываем Flash её место


При внедрении Flash-ролика, которому требуется взаимодействовать со своим сервером по http (например, читать файлы через web), можно указать базовый каталог специально для каждого внедряемого ролика без использования <base>. Для этого в коде внедрения флэшки нужно указать параметр base со значением, равным адресу нужного каталога в «полуабсолютной» форме. То есть в моем случае код внедрения флэшки выглядел следующим образом:
<object …>
<param name="base" value="/flash/">

<embed base="/flash/" src="/flash/01.swf" …>

отдельное спасибо авторам Хабрахабра за «удобные» средства публикации кода


Фактически, я всё так же задал базовый каталог, однако я сделал это только для одного Flash-ролика, без указания протокола и доменного имени (они будут подставлены точно так же, как при разрешении «полуабсолютных» ссылок). Для следующего ролика можно указать другой каталог, или, если вас устраивает работа с корневым каталогом веб-пространства сервера, можно указать просто «/». Flash-технолог теперь всегда может быть уверен в положении флэшки в пространстве веб-сервера и указывать пути к ресурсам удобным ему образом (необязательно как «полуабсолютные»).

P.S.


Если еще кому не очень понятно, призываю к использованию такого метода я исключительно в рамках моего авторитета и на основании моей собственной практики. Именно поэтому я опубликовал топик в личном блоге, а не в соответствующих коллективных.

Если вы не доверяете мне, или по какой-то причине у вас есть своё собственное мнение по этому поводу — предлагаю не разводить лишних дискуссий, а мнение выразить в вашем личном блоге. Здесь же записано лишь моё собственное IMHO, почему <base> вреден, и что делать в его отсутствие.
Теги:
Хабы:
+11
Комментарии 23
Комментарии Комментарии 23

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн