Сайт Романа ПарпалакаБлог20170814

Как определить домен из PHP

14 августа 2017 года, 23:12

Илья Бирман написал про баг в Эгее, когда сайт доступен по разным доменам, и RSS кешируется то с одним доменом, то с другим.

Эгея, чтобы узнать, на каком сервере она работает, смотрит, по какому адресу её открыли — больше ей это узнать неоткуда.

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

HTTP_HOST и SERVER_NAME

Для этих целей обычно проверяют серверную переменную HTTP_HOST. Но в ней всего лишь содержимое заголовка Host из http-запроса. Этот заголовок — часть стандарта HTTP/1.1, и в HTTP/1.0 он не обязателен. Правда, без этого заголовка не заработают виртуальные хосты — разные сайты на общем сервере. Но даже в таком случае среди сайтов есть сайт по умолчанию, открывающийся при заходе напрямую по IP. Так вот, когда устаревшие клиенты (в том числе нормальные браузеры за старыми или специально настроенными прокси) открывают сайт по умолчанию, переменная HTTP_HOST будет пустой.

Есть еще одна серверная переменная — SERVER_NAME. Обычно она содержит хост, определенный в конфигурации веб-сервера. Но на него тоже нельзя стопроцентно положиться. Например, в nginx хост по умолчанию задается конструкцией

server_name _;

Сайт будет прекрасно открываться, но при этом в SERVER_NAME окажется знак подчеркивания.

Подробности для дальнейшего чтения на стековерфлоу: HTTP_HOST vs. SERVER_NAME.

Параметр конфигурации

Если вы делаете распространяемый движок для работы на разных серверах, у вас нет гарантированного способа определить хост, по которому открыт сайт. В моем движке S2 я скопировал способ из PunBB. В нем установочный скрипт «угадывает» адрес сайта (протокол + домен + порт + подпапка) в том числе на основе HTTP_HOST, дает возможность этот адрес отредактировать и сохраняет результат в конфигурационный файл. Затем именно этот адрес используется для генерации ссылок.

Как альтернативу Илья советует настроить редиректы. Это правильно, но, опять же, не всегда выполнимо. Например, вы настроили на сервере https, но не хотите делать редирект с http на https (вы хотите поддерживать старые браузеры, но у вас нет отдельного IP-адреса на каждый домен).

Когда одна и та же страница открывается по разным адресам, Гугл рекомендует в явном виде указывать canonical-адреса:

<link rel="canonical" href="https://example.com/some/url" />

Именно они попадут в поисковую выдачу. Ясно, что движок не сможет сгенерировать такой тег, если не будет знать, на каком из доменов он на самом деле работает.

Кстати, давно хотел написать о том, что https — это новый www. Он вынуждает совершать дополнительные бессмысленные действия при настройке сайта вроде редиректов с www. Ради https мне пришлось сделать в S2 поддержку тега link rel="canonical".

    Оставить комментарий
Поделиться
Записи