Преди повече от 3 години написах публикацията Премахване на .html от URL адреса с mod_rewrite Напоследък в Ganbox извършваме много SEO одити и сега имаме още по-интересен случай със сайт, който има проблем с повтарящи се URL адреси, което може да доведе до наказание на сайта.
Ето някои от URL адресите на сайта, като сме скрили домейна и сме го заместили с домейна zid.bg
http://zid.bg/
http://zid.bg/index.html
http://zid.bg/index.php
http://zid.bg/about.html
http://zid.bg/about.php
http://zid.bg/service_1.html
http://zid.bg/service_1.php
http://zid.bg/product.html
http://zid.bg/product.php
http://zid.bg/product.php?lang=bg
http://zid.bg/product.php?lang=en
http://zid.bg/product.php?lang=gr
Както си вижда много от страниците имат повторения, като началната стнаица има 3 различни URL адреса:
/
/index.html
/index.php
Страницата за продукт, също има 3 URL адреса:
/product.html
/product.php
/product.php?lang=bg
Очевидно този сайт първоначално е бил статичен и всички файлове са имали разширение .html. С развитие на сайта, той е станал динамичен сайт и файловете са получили разширение .php, като никой не се е погрижил за старите .html файлове.
Това което трябва да се направи за този сайт е да се реши следващата:
Задача за премахване на php разширение на уеб страница в адресната лента на браузъра
Скриване на разширението на файла .php и .html. Когато в браузъра се напише http://domain/page.php или http://domain/page.html да се зарежда php файла, но в адреса да се покаже само http://domain/page
Специални изисквания за заместване на URL
Ако в една и съща директория има файл /page.php и поддиректория /page/, то потребителя трябва да получава файла, когато напише /page и директорията, когато напише /page/.
Ако в директорията има файл /page.php и /page.pdf (или някакъв друг различен от php и html), то потребителя трябва да получава от сървъра /page.php, когато напише /page.
Примери за поведение на пренаписващия скрипт
Използва се следния формат: написва в браузъра -> зарежда се -> вижда в адресната лента на браузъра
http://zid.bg/page.php -> http://zid.bg/page.php -> http://zid.bg/page
http://zid.bg/page.html -> http://zid.bg/page.php -> http://zid.bg/page
http://zid.bg/index -> http://zid.bg/index.php -> http://zid.bg/
http://zid.bg/index.html -> http://zid.bg/index.php -> http://zid.bg/
http://zid.bg/index.txt -> http://zid.bg/index.txt -> http://zid.bg/index.txt
http://zid.bg/product.php?lang=en => http://zid.bg/product.php?lang=en => http://zid.bg/product?lang=en
Ако в главната уеб директория има поддиректория /doc и файл /doc.php, а в директорията doc има два файла err.php и index.php
http://zid.bg/doc.html -> http://zid.bg/doc.php -> http://zid.bg/doc
http://zid.bg/doc -> http://zid.bg/doc.php -> http://zid.bg/doc
http://zid.bg/doc/ -> http://zid.bg/doc/index.php -> http://zid.bg/doc/
http://zid.bg/doc/err -> http://zid.bg/doc/err.php -> http://zid.bg/doc/err
http://zid.bg/doc/err.html -> http://zid.bg/doc/err.php -> http://zid.bg/doc/err
Ако в поддиректорията /doc няма index.php, то при написване на http://domain.com/doc/ ще се получи грешка Forbidden.
За началната страница си пише отделен код изключение:
# Ако търси /index или /index.html или index.php RewriteCond %{THE_REQUEST} \ /(.+/)?index(\.html|\.php)?(\?.*)?\ [NC] # го изтрива и оставя само / RewriteRule ^(.+/)?index(\.html|\.php)?$ /%1 [R=301,L]
Този код се грижи при търсене на /index или /index.html или /index.php да се зареди файла /index.php, но в браузъра да се покаже само /
За страниците на други езици адресите ще оставим с параметър lang, това не е най-доброто решение, но в този случай само няколко страници имат превод на друг език, основен език и български и сайта има за цел по-добро позициониране в google.bg. Ето защо не си струва усилията да се ползва друга структура за URL адреси за другите eзици.
За адресите, които имат параметър ?lang=bg правим специално правило изключение с пренасочване към /home, защото в противен случай пак ще има повторение. Езиците различни от български, запазват URL с параметър lang.
Пълният код за .htaccess файла е в следния код:
Решение
# Спира MultiViews (за да може /abc да го търси като /abc.ext преди /abc/) Options +FollowSymLinks -MultiViews DirectoryIndex index.php # Спира mod_dir, за да не добавя наклонена черта в края. DirectorySlash Off RewriteEngine On # Ако започва с www. го премахва RewriteCond %{HTTP_HOST} ^www\. [NC] RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L] # Ако търси /index или /index.html или index.php RewriteCond %{THE_REQUEST} \ /(.+/)?index(\.html|\.php)?(\?.*)?\ [NC] # го изтрива и оставя само / RewriteRule ^(.+/)?index(\.html|\.php)?$ /%1 [R=301,L] # Добавя наклонена черта в края на директория, ако няма файл с .php # Ако търси директория RewriteCond %{SCRIPT_FILENAME}/ -d # и няма php файл с такова име RewriteCond %{SCRIPT_FILENAME}.php !-f # и няма html файл с такова име RewriteCond %{SCRIPT_FILENAME}.html !-f # и няма наклонена черта в края, я добавя. RewriteRule [^/]$ %{REQUEST_URI}/ [R=301,L] # Изтрива PHP разширения # Ако това е заявка от браузър (а не от Apache/mod_rewrite) RewriteCond %{ENV:REDIRECT_STATUS} ^$ # и няма lang=xx параметър RewriteCond %{QUERY_STRING} !(^|&)lang=([a-z]{2})($|&) # и заявката има PHP или HTML разширение, го изтрива. RewriteRule ^(.+)\.(php|html)$ /$1 [R=301,L] # Ако в заявката има .php разширение RewriteCond %{SCRIPT_FILENAME}.php -f # и няма наклонена черта в края, добавя .php, за да зареди файла RewriteRule [^/]$ %{REQUEST_URI}.php [QSA,L]
След качване на .htaccess файла освен проба на това дали работи, трябва да се пусне отново уеб паяк (web crawler), който да обходи сайта и да провери всички достъпни URL адреси. Освен новите, трябва да се виждат и всички стари URL адреси, като те трябва да връщат постоянно пренасочване 301 към новите.
Освен това трябва всички вътрешни линкове да се променят към новите URL. Това включва промяна на менюта и откриване на вътрешни линкове от текста на страниците на сайта.
Дори да не се променят всички стари линкове, те все още ще работят, но ще минават през излишен редирект и ще падне силата им.
Прочетена:9528