Файл .htaccess

Файл .htaccess с таким странным расширением является обычным текстовым файлом. В основном используется для конфигурации сервера Apache.

Файл .htaccess использует такой же формат, как и основной конфигурационный файл для Apache: httpd.conf. Большинство установок можно использовать и в том и в другом файлах. Установки, заданные в файле .htaccess в каталоге, будут иметь более высокий приоритет перед установками, заданными в httpd.conf, для данного каталога и его подкаталогов.

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

Принудительная постановка замыкающего слеша

Код, который всегда будет добавлять слеш в адрес URL сайта.


<IfModule mod_rewrite.c>
 RewriteCond %{REQUEST_URI} /+[^\.]+$
 RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
</IfModule>

Удаление WWW в адресе вашего URL

Например, если вы наберете http://www.site.ru, то вы будете перенаправлены на адрес http://site.ru.


RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.yourdomain\.com$ [NC]
RewriteRule ^(.*)$ http://yourdomain.com/$1 [L,R=301]

Предотвращаем хотлинк ресурсов сайта

Хотлинк (использование изображений вашего сайта другими сайтами в сети) прожигает впустую трафик вашего сервера. Следующий код будет перенаправлять все хотлинк запросы к изображениям вашего сайта на определенную картинку, адрес которой задается в последней строке.


RewriteEngine On
#Замените ?mysite\.com/ на адрес вашего блога
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?mysite\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
#Замените /images/nohotlink.jpg на ваше изображение с запрещением хотлинка
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]

Перенаправляем мобильные устройства

Если ваш сайт не использует адаптивный дизайн, то будет очень полезно перенаправить мобильные устройства на специальную версию сайта.


RewriteEngine On
RewriteCond %{REQUEST_URI} !^/m/.*$
RewriteCond %{HTTP_ACCEPT} "text/vnd.wap.wml|application/vnd.wap.xhtml+xml" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "acs|alav|alca|amoi|audi|aste|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "dang|doco|eric|hipt|inno|ipaq|java|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT}  "maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|opwv" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "palm|pana|pant|pdxg|phil|play|pluc|port|prox|qtek|qwap|sage|sams|sany" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|w3cs|wap-|wapa|wapi" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "wapp|wapr|webc|winw|winw|xda|xda-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "up.browser|up.link|windowssce|iemobile|mini|mmp" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "symbian|midp|wap|phone|pocket|mobile|pda|psp" [NC]
#------------- Строка ниже исключает iPad
RewriteCond %{HTTP_USER_AGENT} !^.*iPad.*$
#-------------
RewriteCond %{HTTP_USER_AGENT} !macintosh [NC]
RewriteRule ^(.*)$ /m/ [L,R=302]

Принудительная загрузка файлов определенного типа

По некоторым причинам вам может потребоваться принудительная загрузка файлов определенных типов (например, MP3 или XLS). Нижеприведенный код будет предотвращать чтение таких файлов браузером и принудительно запускать загрузку.


<Files *.xls>
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</Files>
<Files *.eps>
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</Files>

Ограничение на определенные расширения файлов

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


Options -ExecCGI
AddHandler cgi-script .js .cgi .asp .jsp. htm .exe .sh

Перенаправления и изменение URL

Если вам нужно изменять имя домена или перестраивать файловую структуру проекта, или делать длинные трудно запоминаемые адреса URL простыми и понятными, то вам поможет .htaccess.

Перенаправления могут быть простыми:


Redirect 301 ^old\.html$ http://localhost/new.html

В данном случае используется код статуса HTTP 301 (перемещено постоянно) и все запросы к странице old.html перенаправляются на new.html. Здесь используется регулярное выражение для определения соответствия URL правилу, что добавляет сложности в построение правила, но придает уверенности в правильности URL. Требуется указывать полный адрес URL ресурса, на который происходит перенаправление.

Правило изменения также может быть очень простым:


RewriteEngine on
RewriteRule ^old\.html$ new.html

В данном примере происходит простое перенаправление с одного файла на другой, которое выполняется прозрачно, без изменения содержания адресной строки в браузере. Первая директива RewriteEngine on гарантирует, что механизм изменения запущен.

Чтобы обновить содержание адресной строки браузера, мы можем использовать флаг r в конце правила RewriteRule:


RewriteRule ^old\.html$ http://hostname/new.html [r=301]

Флаг приводит к внешнему перенаправлению, поэтому адрес URL будет соответствовать новой странице. Также можно использовать код статуса для флага, что приведет к обновлению страницы в браузере посетителя.

Одно возможное использование перенаправлений - изменение адресов URL к более простой форме для посетителей и поисковых роботов. Рассмотрим пример:


RewriteRule ^products/([^/]+)/([^/]+)/([^/]+) product.php?cat=$1&brand=$2&prod=$3

Данное правило позволяет использовать посетителю адрес URL наподобие products/turntables/technics/sl1210, который будет трансформироваться в product.php?cat=turntables&brand=technics&prod=sl1210. Круглые скобки между слешами в регулярном выражении примера выполняют объединение в группы – мы можем использовать каждую из них как $1, $2 и $3 соответственно. Комбинация [^/]+ в скобках соответствует любому символу, кроме слеша, в любых количествах.

На практике, изменение URL имеет существенно более сложные правила, чем описанные в наших примерах, но они позволяют решить очень сложные задачи.

Пользовательская страница ошибок 404

Сервера имеют свою стандартную страницу 404. Вы можете создать собственную страницу ошибок, которая соответствует по стилю остальному содержанию и несет дополнительную информацию.


ErrorDocument 404 "/404.html"

Если происходит ошибка 404, будет выводиться указанная страница. Также можно сделать страницы для отображения других серверных ошибок.


ErrorDocument 401 /401.php
ErrorDocument 403 /403.php
ErrorDocument 404 /404.php
ErrorDocument 500 /500.php

Ограничения доступа к определённым ресурсам

Можно ограничить доступ к любому файлу или каталогу:


AuthName "Введите имя пользователя и пароль"
AuthUserFile /path/to/.htpasswd
Require valid-user
AuthType Basic

Файл нужно разместить в каталоге, который требуется защитить от свободного доступа. Директива AuthName определяет сообщение, которое будет выводиться в диалоговом окне для ввода пароля, а в правиле AuthUserFile определяется путь к файлу .htpasswd. Директива Require определяет, что только зарегистрированные пользователи могут получить доступ к файлу.

Для защиты определенного файла нужно заключить выше приведенный код в директиву <files>, в которой определяется имя файла:


<Files "protectedfile.html">
   AuthName "Введите имя пользователя и пароль"
   AuthUserFile /path/to/.htpasswd
   Require valid-user
   AuthType Basic
</Files>

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

Блокируем доступ для определенных посетителей

Быстрое и простое блокирование всех запросов с определенного IP адреса или агентов. Нужно просто добавить в файл правила:


order allow,deny
deny from 192.168.0.1
allow from all

Директива order указывает серверу Apache в каком порядке рассматривать директивы allow/deny. В примере директива allow оценивается первой, а затем следует работа с deny. Правило allow from all рассматривается первым (несмотря на то, что в файле оно определено после правила deny) и все IP адреса разрешаются. Затем, если IP адрес клиента соответствует указанному в директиве deny, то доступ ему блокируется. Можно блокировать доступ диапазону IP адресов, указав, например, 192.168.

Для блокирования доступа определенным агентам, можно использовать другие правила:


RewriteCond %{HTTP_USER_AGENT} ^OrangeSpider
RewriteRule ^(.*)$ http://%{REMOTE_ADDR}/$ [r=301,l]

В данном примере любой клиент, у которого строка HTTP_USER_AGENT начинается с OrangeSpider (плохой бот), будет перенаправлен по адресу, с которого пришел. Регулярное выражение соответствует любому единичному символу (.) в любых количествах (*), а для адреса используется переменная %{REMOTE_ADDR}. Флаг l указывает для сервера Apache, что данное правило является последним для клиента и никаких других операций для него выполнять не нужно.

Включаем кеширование

Кеширование очень просто устанавливается и делает загрузку вашего сайта быстрее. Устанавливая дату обновления для ресурсов, которые редко изменяются, мы можем предотвратить многократную повторяющуюся загрузку той части содержания, которая остается неизменной.


ExpiresActive on
ExpiresByType image/gif                 "access plus 1 month"
ExpiresByType image/png                 "access plus 1 month"
ExpiresByType image/jpg                 "access plus 1 month"
ExpiresByType image/jpeg                "access plus 1 month"
ExpiresByType video/ogg                 "access plus 1 month"
ExpiresByType audio/ogg                 "access plus 1 month"
ExpiresByType video/mp4                 "access plus 1 month"
ExpiresByType video/webm                "access plus 1 month"

Вы можете добавлять правила ExpiresByType для любых типов содержания. Директива ExpiresActive on просто включает генерацию заголовка устарения ресурса. Данная директива зависит от наличия модуля mod_expires на сервере Apache.

Сжатие

Использование сжатия:


FilterDeclare   COMPRESS
FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/html
FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/css
FilterProvider  COMPRESS  DEFLATE resp=Content-Type $text/javascript
FilterChain     COMPRESS
FilterProtocol  COMPRESS  DEFLATE change=yes;byteranges=no

Данная схема сжатия работает на новых версиях Apache (2.1+) с установленным модулем mod_filter. Он использует алгоритм DEFLATE для сжатия содержания. В примере мы указываем text/html, text/css и text/javascript в качестве типов ресурсов, которые будут сжиматься.

Определение фильтра начинается с директивы FilterDeclare с опцией COMPRESS. Затем перечисляются типы содержания, на которые будет действовать фильтр. Правило FilterChain указывает серверу построить цепочку на основании списка правил FilterProvider. Директива FilterProtocol позволяет задавать опции, которые используются фильтром при выполнении. Необходимо указать опции change=yes (содержание может изменяться фильтром (в нашем примере - сжиматься)) и byteranges=no (фильтр может использоваться только к полным файлам).

Кодировка

Моё первое знакомство с файлом началось с решения этой проблемы.

Однажды возникла проблема - при размещении рекламных ссылок на сайте выяснилось, что биржа ссылок проверяла правильность ссылок на моем сайте и считала, что у меня установлена кодировка windows-1251, хотя на всех страницах сайта в теге meta была прописана требуемая кодировка utf-8. Оказалось, что настройки сервера имеют больший приоритет, чем meta-настройки. Естественно, хостер не будет менять настройки сервера для вас. Но, можно решить проблему через файл .htaccess. Достаточно прописать в файле строчку:


AddDefaultCharset utf-8

Записываем ошибки PHP в журнал

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


# отключаем вывод ошибок пользователям
php_flag display_startup_errors off
php_flag display_errors off
php_flag html_errors off
# заносим ошибки в журнал
php_flag log_errors on
php_value error_log /location/to/php_error.log
Реклама