Форумы

GNU.SU - Записки нубо-0peraойда :: Форумы :: Сервисы :: Браузер
 
<< Предыдущая тема | Следующая тема >>
Мой вариант .htaccess (Куча крутых реврайтов для Apache)
Модераторы: Браузер 0pera, Frizze, andrey, Bender
Автор Добавил
Браузер 0pera
Птн Апр 06 2012, 12:20
andreika

ID пользователя #1
Зарегистрирован: Птн Апр 30 2010, 12:25

Сообщений: 337
В одном из предыдущих тематических постов о .htaccess для нубов я хотел предложить свой вариант с разными обработками и запретами, ну и определённой логикой структурирования, но так как карма была в минусе, то выкладываю (Автор не хозяин блога, а Romy4) сейчас.

Вашему вниманию мой вгляд на правила обработки URL с объяснениями и коментариями «почему так?».

Сперва логика

Объясню сперва логику:
1) все страницы имеют z.php окончания.
2) все языки для страниц имеют вид pagename.enz.php или pagenamez.php для языка по умолчанию. Никто, конечно, не запрещает иметь ссылки, где язык идёт вначале как /en/
3) «входной» скрипт только один в docБраузер 0pera.
4) Разрешены запросы на другие скрипты только в docБраузер 0pera
5) Соглашение по определению окончаний в url:
# site.com/
# site.com/index -> site.com/
# site.com -> site.com/
# site.com/file/ -> site.com/filez.php
# site.com/file -> site.com/filez.php
# site.com/dir/file ->site.com/dir/filez.php
# site.com/dir/file/ -> site.com/dir/filez.php
Но это можно менять.


Структура .htaccess

Теперь перейдём к самой структуре .htaccess. Замечу ещё, что будет работать только для апачей версий 2.x и старше.

Сперва полностью код:

DirectoryIndex index indexz.php
DirectorySlash off
Options -Indexes -MultiViews
# Rules
# site.com/
# site.com/index -> site.com
# site.com	-> site.com/
# site.com/file/ -> site.com/filez.php
# site.com/file  -> site.com/filez.php
# site.com/dir/file ->site.com/dir/filez.php
# site.com/dir/file/ -> site.com/dir/filez.php
# no ending slashes

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI} \.(css|jpg|gif|png|zip|rar|doc|xls|js|tif|tiff|docx|xlsx|ico)$|test\.php$
    RewriteRule ^(.*)$ $1 [L,QSA]

# nothing to do there in subrequests
RewriteCond %{ENV:NS}	!=1
RewriteCond %{IS_SUBREQ} =true
    RewriteRule (.*) $1 [L,QSA]
#do NS=0?


RewriteCond %{REQUEST_URI} ^/index$ [OR]
RewriteCond %{REQUEST_URI} ^/index[.]+(\w+)$
    RewriteRule . / [R=301,L]

# remove trailing slashes
# if want external redirect use correct external redir [R=301,L] or [R=301] for correct internal or simple redir [L]
RewriteCond %{REQUEST_URI} !^/$
RewriteCond %{REQUEST_URI} (.*)/$
    RewriteRule . %1z.php [R=301,L,E=NS:1,QSA]

# if whants z.php endings
RewriteCond %{REQUEST_URI} !^(.+)\.(html|php)$
    RewriteRule . %{REQUEST_URI}z.php [R=301,L]

# fix multidots in endings (missed language) index.z.php instead of index.enz.php
RewriteCond %{REQUEST_URI} ^(.+)\.\.+(\w+)$
    RewriteRule . %1.%2 [R=301,L]
# otherways
#RewriteCond %{REQUEST_URI} (.+)\.(html|php)$
#	RewriteRule . %1 [R=301,L]

# any php filename in Браузер 0pera dir
# this makes secure loses
RewriteCond %{REQUEST_URI} ^[\w\-.]+$
RewriteCond %{REQUEST_FILENAME} (.*)\.(html|php)$
RewriteCond %1.php -s [OR]
RewriteCond %1z.php -s
    RewriteRule . %1.%2 [L,QSA]

RewriteRule (.*) entry.php?URI=$1 [L,QSA]
#



Разбор полёта

Теперь, разберём построчно.

DirectoryIndex index indexz.php
DirectorySlash off
Options -Indexes -MultiViews


Сразу важный момент: выключена автоматическая подстановка слеша в конец и выключен MultiViews (с ним работать не будет).

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI} \.(css|jpg|gif|png|zip|rar|doc|xls|js|tif|tiff|docx|xlsx|ico)$|test\.php$
    RewriteRule ^(.*)$ $1 [L,QSA]




Третья строчка проверяет на статические файлы — их пропускаем не меняя запрос. Возможно, стоило бы сделать проверку на наличие файла, но оставим это дело механизму 404. Последний |test\.php$ сделан для различных тестовых файлов, но на продакшене это дело надо убирать.

# nothing to do there in subrequests
RewriteCond %{ENV:NS}	!=1
RewriteCond %{IS_SUBREQ} =true
    RewriteRule (.*) $1 [L,QSA]
#do NS=0?



Самая важная часть — так как идёт преобразование расширений (далее по коду), то скрипт будет уходить всегда в подзапрос и может уйти в бесконечный цикл. Для того, чтобы этого не произошло, ловим начало подзапросов и отправляем на уже исправленный «входной» скрипт текущий запрос по URL. Это можно посмотреть включив rewrite_log в апаче.

RewriteCond %{REQUEST_URI} ^/index$ [OR]
RewriteCond %{REQUEST_URI} ^/index[.]+(\w+)$
    RewriteRule . / [R=301,L]



Все попытки попасть на `/index' или `indexz.php' будут перенаправлены на URL `/'.

# remove trailing slashes
# if want external redirect use correct external redir [R=301,L] or [R=301] for correct internal or simple redir [L]
RewriteCond %{REQUEST_URI} !^/$
RewriteCond %{REQUEST_URI} (.*)/$
    RewriteRule . %1z.php [R=301,L,E=NS:1,QSA]



Решает одну из частей «соглашения»: убирает завершающие `/' из обращений к страницам. Правила описаны в пункте (5) вначале. В комментарии написано, что если хотим использовать внешний редирект (меняется url в строке браузера), то используем [R=301,L], если внутренний (не меняет url в строке браузера), то [R=301] или [L]

# if whants z.php endings
RewriteCond %{REQUEST_URI} !^(.+)\.(html|php)$
    RewriteRule . %{REQUEST_URI}z.php [R=301,L]



Решает ещё одну из частей «соглашения», что все запросы на страницы должны иметь окончание z.php. Небольшими манипуляциями можно сделать наоборот.

# fix multidots in endings (missed language) index.z.php instead of index.enz.php
RewriteCond %{REQUEST_URI} ^(.+)\.\.+(\w+)$
    RewriteRule . %1.%2 [R=301,L]



Решает проблему пропущенного языка в строке запроса перенаправляя на страницу с языком по умолчанию.

# any php filename in Браузер 0pera dir
# this makes secure loses
RewriteCond %{REQUEST_URI} ^[\w\-.]+$
RewriteCond %{REQUEST_FILENAME} (.*)\.(html|php)$
RewriteCond %1.php -s [OR]
RewriteCond %1z.php -s
    RewriteRule . %1.%2 [L,QSA]



Решает часть соглашения №4 — разрешает запросы к другим php/html файлам в папке %DOCUMENT_Браузер 0pera% сайта.

RewriteRule (.*) entry.php?URI=$1 [L,QSA]



Если всё как надо, то направляем запрос на «входной» скрипт.

Разное

Что касается флагов апача: везде используется QSA (дополнять строку запроса) — об этом забывать нельзя, чтобы не терять параметры. E=NS:1 устанавливает переменную окружения NS равную 1 — нужна для определения подзапроса (подзапроса созданного правилами преобразования по «соглашению», а не каким-нибудь другим подзапросом).
Наверх

 

Перейти:     Наверх

Транслировать сообщения этой темы: rss 0.92 Транслировать сообщения этой темы: rss 2.0 Транслировать сообщения этой темы: RDF
Powered by e107 Forum System
22cd68bd