#1 Online pharmacy affiliate program! Инвайты в ICQ
 
Feb
09
Posted (Random) on February 09-2007

Буквально на днях столкнулся с интересной проблемой. Всем известно, что гугл, как и прочие поисковики, воспринимает домены site.ru и www.site.ru как два совершенно независимых сайта и упорно индексирует все документы сначала на домене без www, а потом и с ним, съедая при этом изрядную долю вашего трафика, который, как известно, не резиновый, и если халявная месячная норма трафика на хостинге кончится, придётся выкладывать свои родные, потом и кровью заработанные, зелёные шуршащие бумажки.




И всё из-за какого-то тупого бота. Хотя нет, наверное не тупого, ибо в гугле не дураки работают, и всё не просто так.




Итак, чтобы не заставлять бота два раза бегать по одним и тем же документам, и чтобы сэкономить наш трафик, который уходит в небытие, напишем в файле .htaccess в корне нашего сайта такие волшебные строчки:



  1. RewriteEngine On

  2. RewriteRule ^.htaccess$ - [F]


  3. RewriteBase /

  4. RewriteCond %{HTTP_HOST} ^www\.yourdomain\.com$

  5. RewriteRule ^(.*)$ http://yourdomain.com/$1 [R=301,L]


Строки пронумерованы только для наглядности, не вздумайте писать эти циферки в самом файле :)




Итак, первой строкой мы включаем возможность преобразования урлов, второй - не разрешаем смотреть содержимое файла .htaccess. Хитрый юзер, который наберёт в браузере http://site.ru/.htaccess, желая поближе познакомиться с вашим ресурсом в интернете, увидит сообщение об ошибке "403 Forbidden".




Теперь, собственно, то, ради чего всё затеяно. Четвёртой строкой устанавливаем путь от корня папки, в которой лежит .htaccess до директории, в которой будем производить замены урлов. В нашем случае, поскольку мы пока рассматриваем корень сайта, это будет "/". Далее идёт условие RewriteCond, и если оно выполнено, то есть если обращение было к www.yourdomain.com, то сработает следующее за ним правило замены RewriteRule. Но только одно, если требуется несколько правил, для каждого нужно писать RewriteCond отдельно. У нас RewriteRule перенаправляет любой запрос 301-м редиректом в http://yourdomain.com/, подставляя его же, после слэша.




Какой редирект лучше использовать, 301-й (Moved Permanently) или 302-й (Moved Temporarily), вроде бы с точки зрения сео, не важно. Какой вам больше нравится.




Теперь начинается самое интересное. А что если у нас на сайте есть директория, в которой тоже куча скриптов, вот, например, этот самый блог. Вроде бы тут всё ясно, копируем .htaccess из корня в /blog/, не забывая изменить RewriteBase и в RewriteRule прописать http://yourdomain.com/blog/ и всё работает. Ан-нет. Попробуйте набрать в браузере: http://www.yourdomain.com/blog. Ага. Ошибка 404 - не найдено?




Ещё где-то мне довелось прочитать, что если ИЕ в избранное подсунуть подобную ссылку, только со слэшем в конце, то он тот слэш забудет. Сам не испытывал, но с учётом количества косяков и осле, можно принять эту гипотезу как верную. И что получается, пользователь пришёл на страничку со слэшем в конце, ему понравилось, добавил в избранное, а вернуться не может. Видит 404 и ничего понять не может. Это, конечно, только совсем неопытный юзер не догадается попробовать дописать слэш в конец, но тем не менее.




Здесь сразу напрашивается простое решение. Дописать вопросительный знак после последнего слэша в шестой строчке:

RewriteRule ^(.*)$ http://yourdomain.com/blog/?$1 [R=301,L]

И если мы теперь снова попытаемся открыть страницу http://www.yourdomain.com/blog, невероятным образом увидим путь от корня операционной системы хостинга до несчастной папки /blog. Таким образом, мы палим свой логин на хостинге. Весело-то как. По крайней мере на моём хостинге именно так. А на нём хостится немало народу, даже не подозревающих об этом подвохе.




Решение не заставило себя долго ждать, однако, оно несколько нетривиально. Нужно всего-то дописать перед RewriteCond такую строчку:
RewriteCond %{REQUEST_FILENAME} !-d
Которая проверяет, является ли строка (то есть кусок урла от RewriteBase) не директорией. Здесь начинаются непонятки, лично для меня.




Мы имеем два условия, и если они одновременно выполнены, то срабатывает преобразование урла, то есть редирект на домен без www. В таком случае, нас интересуют варианты:


http://www.yourdomain.com/blog

http://www.yourdomain.com/blog/

http://www.yourdomain.com/blog/script.html

Во всех случаях, срабатывают оба условия! Если с последним всё ясно, оно - не директория, то первые два заставляют задуматься. И опытым путём выяснилось, что строка:

RewriteBase /blog/

На результат редиректа не влияет ни коим образом.




Всё, конечно, работает, но когда оно работает не понять как, это вызывает некоторые опасения.




Что касается редиректов, которые происходят уже непосредственно внутри php-скрипта, то можно устроить вот такой редирект обращениям с www:



if(!strstr($_SERVER['HTTP_HOST'],"www."))
{
$host = substr($_SERVER['HTTP_HOST'],4);
$uri = $_SERVER['REQUEST_URI']
Header("HTTP/1.1 404 Not Found");
Header("Location:http://".$host.$uri);
exit;
}

Но всё же те задачи, которые можно решить ресурсами апача, нужно ими и решать. Так что дружно юзаем .htaccess.




Последнее, если вдруг кто-то набрал неправильный урл, или пришёл по неправильной ссылке, лучше бы его вежливо так средиректить на индекс, не забывая про такую вещь, как сео:



Header("HTTP/1.0 301 Moved Permanently");
Header("Location: http://".$_SERVER['HTTP_HOST']."/index.html");

"Тогда эти неверные ссылки стопудово склеятся с верными, и
с точки зрения сео все будет хорошо." - говорю я, словами Мастера Ласто, который плохого не посоветует.