.htaccess

15.10.2014

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

А как же быть, если нужно настроить несколько редиректов, и совсем нет времени познавать всю мощь .htaccess? Единственный выход это брать готовые примеры, и наугад адаптировать под свои нужды. В этой статье я напишу краткое руководство по .htaccess, которое закроет большинство вопросов новичков. А также приведу ссылки на подробные инструкции. Эта статья будет дописываться по мере необходимости, начну с самого основного.

Редиректы

Редиректы осуществляются с помощью модуля mod_rewrite. Задаются правила преобразований в виде следующей конструкции:


<IfModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine On

  [СЮДА ПИШЕМ ПРАВИЛА]  

</IfModule>

Правила преобразования записываются в таком виде:


RewriteCond [СТРОКА ДЛЯ СРАВНЕНИЯ] [УСЛОВИЕ] [ФЛАГИ]
RewriteCond [СТРОКА ДЛЯ СРАВНЕНИЯ] [УСЛОВИЕ] [ФЛАГИ]
RewriteRule [ШАБЛОН] [СТРОКА ПОДСТАНОВКИ] [ФЛАГИ]

Строки RewriteCond - задают условия для срабатывания следующего за ними правила RewriteRule. Условий может быть несколько, они накладываются по правилу AND. Но можно изменить правило на OR с помощью флага OR.

В качестве [СТРОКИ ДЛЯ СРАВНЕНИЯ] могут использоваться различные переменные. Ссылка на полный список Я приведу только те, которые нужны чаще всего:

%{REQUEST_URI} Строка запроса (без доменного имени, и GET параметров), пример "/server/htaccess/"
%{HTTP_HOST} Доменное имя, например "max22.ru"
%{QUERY_STRING}Строка GET параметров

[УСЛОВИЕ] также как и [ШАБЛОН] представляют собой perl совместимое регулярное выражение, с некоторыми дополнениями, позволяющими например проверить файл ли это, или существующий url.

[ФЛАГИ] Флаги пишутся в квадратных скодках через запятую: [NC,OR]. Флаги для условий:

NC Регистронезависимая проверка
OR Условие сопостовляется с остальными про правилу ИЛИ

Подвыражения в регулярных выражениях (заключенные в скобки), доступны для вставки в [СТРОКУ ПОДСТАНОВКИ], обращаться к подвыражениям нужно так: %N - для подвыражений в условиях (RewriteCond) и $N - для подвыражений в правилах (RewriteRule), где N - порядковый номер подвыражения.

RewriteRule - правило подстановки. Если запрос подходит под вышестоящие проверки и [ШАБЛОН], то применяется правило подстановки. Здесь регулировать поведение также можно с помощью флагов. Флаги есть разные, приведу наиболее часто используемые:

NC Регистронезависимая проверка
R=301 Будет редирект с кодом 301, можно указать другой код
L Это последнее правило, больше не применять правил преобразований

Надеюсь после моего краткого ввода в теорию, вам будет проще понимать что же написано в вашем .htaccess. Привожу ссылку на очень хороший перевод про модуль mod_rewrite, там же можно найти другие хорошие переводы.

Внимание! Браузеры кешируют редиректы!!!

Причем обычные сочетания типа Ctrl+F5 или Ctrl+R не помагают. Я во время тестирования каждый раз открываю страницу в НОВОМ окне в режиме инкогнито. Причем старые страницы в режими инкогнито надо закрывать.

Примеры

Универсальный редирект с www на без www

Тут самое интересное, почему то везде приводятся примеры, жестко привязанные к домену сайта. Зачем?, если есть универсальное решение:


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

Проверяем доменное имя, если оно начинается с www, то сработает правило: "все, на http://%1/$1". Здесь %1 это наш домен без www (взят из условия), а $1 это адрес (взят из самого правила).

Универсальный редирект с без www на www


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

Тут маленько сложнее. Первое условие нужно для того чтобы получить домен (%1), оно всегда истина. Второе условие проверяет, что домен начинается не с www. Ну и само правило, аналогичное предыдущему примеру

Простой редирект


RewriteRule ^news/happy.* /news.html [R=301,L]

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

Реврайт без редиректа


RewriteRule ^news/happy.* /news.html [L]

Иногда требуется, чтобы был редирект без смены адреса, т.е. реврайт без редиректа. Для этого просто не указываем флаг редирект (R), и получаем желаемый результат, теперь по адресу news/happy получим news.html, а в адресной строке останется news/happy

Редирект от GET параметров

Например, нужно что бы со страницы /?action=page&id=15 был редирект на /page/15/:


RewriteCond %{QUERY_STRING} action=page [NC]
RewriteCond %{QUERY_STRING} id=(\d+) [NC]
RewriteRule .* /page/%1/? [R=301,L]

Поясню, первым условиям проверяем что есть get параметр action=page, вторым условием проверяем что id равно числу. Эти условия нельзя объединять, т.к. параметры могут идти и наоборот, т.е. index.php?action=page&id=15 и index.php?id=15&action=page должны быть равноценны. Но и наконец правило, там все обычно, кроме знака вопрос (?) на конце. Он нам нужен, чтобы отсечь исходные GET параметры, иначе получим /page/15/?action=page&id=15

Редирект на мобильную версию сайта

Допустим, что мобильная версия расположена на поддомене m.site.ru. Будем переходить на мобильную версию только с главной страницы основного домена.


RewriteCond %{HTTP_USER_AGENT} (?i:midp|samsung|nokia|j2me|avant|docomo|novarra|palmos|palmsource|opwv|chtml|pda|mmp|blackberry|mib|symbian|wireless|nokia|hand|mobi|phone|cdm|upb|audio|SIE|SEC|samsung|HTC|mot-|mitsu|sagem|sony|alcatel|lg|eric|vx|NEC|philips|mmm|xx|panasonic|sharp|wap|sch|rover|pocket|benq|java|pt|pg|vox|amoi|bird|compal|kg|voda|sany|kdd|dbt|sendo|sgh|gradi|jb|dddi|moto|iphone|android) [NC] 
RewriteCond %{HTTP_HOST} site.ru
RewriteRule ^$ http://m.site.com/ [R=302,L]

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

Второй строкой проверяем что мы находимся на нужном домене (т.к. пример не универсальный)

Третьей строкой, мы проверяем, что находимся на главной страницы (без всяких параметров и прочего) и перенаправляем на поддомен.

Универсальная версия

Я люблю, чтобы все было универсально, чтобы один и тот же код работал на разных проектах без каких - либо правок. Для этого я переделал предыдущий пример:


RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteCond %{HTTP_USER_AGENT} (?i:midp|samsung|nokia|j2me|avant|docomo|novarra|palmos|palmsource|opwv|chtml|pda|mmp|blackberry|mib|symbian|wireless|nokia|hand|mobi|phone|cdm|upb|audio|SIE|SEC|samsung|HTC|mot-|mitsu|sagem|sony|alcatel|lg|eric|vx|NEC|philips|mmm|xx|panasonic|sharp|wap|sch|rover|pocket|benq|java|pt|pg|vox|amoi|bird|compal|kg|voda|sany|kdd|dbt|sendo|sgh|gradi|jb|dddi|moto|iphone|android) [NC]
RewriteRule ^$  http://m.%1 [R=302,L]

Редирект с главной страницы

Речь идет про запрос типа site.ru (без site.ru/index.php)

Здесь оказалось не все так очевидно, я столкнулся с необъяснимым поведением.

Реврайт без редиректа (урл не меняется). Рабочий вариант:


RewriteRule ^index.php$  /about/ [L]

Редирект. НЕ рабочий вариант:


RewriteRule ^index.php$  /about/ [R=301,L]

Реврайт без редиректа (урл не меняется). НЕ рабочий вариант:


RewriteRule ^$  /about/ [L]

Редирект. Рабочий вариант:


RewriteRule ^$  /about/ [R=301,L]

Если мне кто - нибудь расскажет почему эти примеры работают крест накрест, а обратно не работают - буду очень рад.

Комментарии:

Harry

15.02.2014 16:44:22

Супер статья, но у меня ?
как ссылки вида www.site.ru/?mod=([a-z])&id=([0-9])&page=([0-9])
сделать редирект/реврайт
на ссылки вида www.site.ru/index.php?mod=([a-z])&id=([0-9])&page=([0-9])
(там есть нюансы, даже хостер тупит и не может дать правильный ответ - получается или 500 или бесконечный редирект...)
С уважением Игорь

Harry

15.02.2014 18:42:40

Решено, может кому надо:
RewriteCond %{THE_REQUEST} !^GET.*index.php.* [NC]
RewriteCond %{THE_REQUEST} ^GET.*\?.+ [NC]
RewriteRule ^(.*)$ /index.php$1 [L]

Максим

16.02.2014 08:52:58

Не совсем так.
У вас любой запрос не содержащий index.php уйдет на /index.php, включая файлы стилей (если они не через nginx), также страница типа max22.ru/server/ тоже уйдет на http://max22.ru/index.phpserver
Вам надо такие правила:

RewriteCond %{REQUEST_URI} ^/$ [NC]
RewriteCond %{QUERY_STRING} ^(.+)$ [NC]
RewriteRule ^(.*)$ /index.php?%1 [R=301,L]

первая строка означает что запрос должен быть пустой, т.е. max22.ru, max22.ru/server сюда уже не пройдет
вторая строка означает что должны быть get параметры (хоть один)
и третья строка что все get параметры отправляем на /index.php?

Алексей

04.04.2014 16:06:21

Здравствуйте!
А вот а таком случае что делать?
Бьюсь уже несколько дней....
нужно редерект с

http://site.ru/catalog/catalog.php?id=596
на

http://site.ru/catalog/596

Максим

04.04.2014 17:40:01

RewriteCond %{REQUEST_URI} ^/catalog/catalog.php [NC]
RewriteCond %{QUERY_STRING} id=([0-9]+) [NC]
RewriteRule .* /catalog/%1? [R=301,L]

первой строкой определяем то, что запрашивается /catalog/catalog.php
второй строкой получаем числовое значение параметра id
и сам редирект

Алексей

04.04.2014 18:36:48

Спасибо огромное Максим!!!!!!!!!!!!!!!!!!!
Всё работает!!!!!

Вячеслав

09.04.2014 15:08:51

Есть урл вида: http://site.ru/collections/([A-Z]+)/?KOL=([A-Z]+)&PAGEN_1=([0-9]+)
нужно получить: http://site.ru/collections/([A-Z]+)/?PAGEN_1=([0-9]+)

Делал так:
RewriteCond %{QUERY_STRING} ^KOL=([A-Z]+) [NC]
RewriteCond %{QUERY_STRING} PAGEN_1=([0-9]+) [NC]
RewriteRule .* /collection/%1/\?PAGEN_1=%2? [R=301,L]

не получается.
Спасибо!

Вячеслав

09.04.2014 16:13:28

Задачу решил, нужно было так:

RewriteCond %{QUERY_STRING} ^KOL= [NC]
RewriteCond %{QUERY_STRING} PAGEN_1=([0-9]+) [NC]
RewriteRule ^(.*)$ $1\?PAGEN_1=%1 [R=301,L]

Может кому пригодиться решение.

Виктор

09.08.2014 21:03:00

а как перенаправить сайт: сайт.ru/#content на сайт.ru ?

Максим

10.08.2014 07:46:02

#hash не передается на сервер. По этому и редирект в зависимости от #hash сделать не получится:(

Harry

17.10.2014 14:25:40

Может кому надо - динамичное (сегодня нужна одна главная - через месяц захотели другую) переопределение главной страницы DirectoryIndex со склейкой зеркала (если просто index.php без подзапроса - то строчка с RewriteCond не нужена)
#Переопределение главной страницы
DirectoryIndex /index.php?mod=main&id=1
#Склейка зеркала главной страницы
RewriteCond %{QUERY_STRING} ^mod=main&id=1$
RewriteRule ^index.php$ /? [R=301,L]

Виктор

22.01.2015 15:19:24

Не подскажите, как сделать перенаправлление с поддомена http://napol32.ru.62-152-34-99.ppa.listkom.ru/ на napol32.ru/404.php
сам пытался написать, но ложился сам сайт

Виктор

22.01.2015 15:35:49

Пишу такое, но не работает
RewriteCond %{HTTP_HOST} ^napol32\.ru\.62-152-34-99\.ppa\.listkom\.ru.*$
RewriteCond %{REQUEST_URI} !/napol32\.ru/.*
RewriteRule ^(.*)$ napol32.ru/404.php [R=301, L]

Максим

22.01.2015 16:32:54

Виктор, у вас лишний пробел во флагах, и не хватает http://. И вторая строка лишняя, нужно так:
RewriteCond %{HTTP_HOST} ^napol32\.ru\.62-152-34-99\.ppa\.listkom\.ru.*$
RewriteRule ^(.*)$ http://napol32.ru/404.php [R=301,L]

Виктор

22.01.2015 17:00:41

Большое спасибо

Виктор

22.01.2015 17:32:20

Не подскажите ещё один редирект
нужно с http://www.tkrkt.ru/news/vystavka-pir?offset=70 на
http://www.tkrkt.ru/news/vystavka-pir, т е без get параметров

написал такое
RewriteCond %{REQUEST_URI} ^/news/(.+) [NC]
RewriteCond %{QUERY_STRING} ^.+$ [NC]
RewriteRule ^(.*)$ /news/%1 [R=301,L]
по идее же должны вынимать в %1 vystavka-pir и подставлять в наш адрес, а получаеться наоборот, что подставляет только гет строку
Не подскажите, в каком месте я допускаю ошибку ?

Максим

22.01.2015 19:44:22

Виктор, ваш пример оказался не таким очевидным. Я опять столкнулся с необъяснимым поведением, если поменять условия местами - то все работает:

RewriteCond %{QUERY_STRING} ^.+$ [NC]
RewriteCond %{REQUEST_URI} ^/news/(.+)$ [NC]
RewriteRule ^(.*)$ /news/%1? [R=301,L]

И в правиле нужно в конце "?" поставить - чтобы GET параметры отбросились

Денис

27.01.2015 14:15:41

В тему двум последним ответам
Необходимо из site.ru/services/rubka-listovogo-metalla?id=32
Перенаправить в site.ru/services/rubka-listovogo-metalla

Пробовал
RewriteCond %{QUERY_STRING} ^.+$ [NC]
RewriteCond %{REQUEST_URI} ^/services/(.+)$ [NC]
RewriteRule ^(.*)$ /services/%1? [R=301,L]

И так
RewriteCond %{REQUEST_URI} ^/services/(.+) [NC]
RewriteCond %{QUERY_STRING} ^.+$ [NC]
RewriteRule ^(.*)$ /services/%1 [R=301,L]

Максим

27.01.2015 17:02:30

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

Алексей

18.02.2015 22:47:03

Здравствуйте, Максим.
Статья супер, нигде не встречал таких решений. Сам стремлюсь делать универсальные решения, но ваши примеры победили мои. Забрал склейку доменов с www и без него.
Максим, у меня появилась проблема с поисковиком Яндекс и его браузером. Много переписывался с техподдержкой Яндекса, но пользы никакой.
Проблема в том, что Яндекс в адреса страниц с моего сайта вставляет код, с которым редирект не работает и убрать этот код проблематично. Мне удалось только через два 301 редиректа привести адрес странички в рабочее состояние. Но, по всей видимости, срабатывает движок сайта и при редиректах лишний код удаляется из адреса.
Вот что получается из нормального адреса
http://www.site.ru/forum/tema.php?t=хххх
в Яндексе
http://www.site.ru/forum/%0D%0Atema.php?t=хххх

При наборе адреса со встроенным кодом %0D%0A сервер отдаёт 404 ошибку.
Моё решение
RewriteEngine on
RewriteBase /~quux/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule tema(.*)$ http://site.ru/forum/tema$1 [R=301,L]

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

Олеся

04.03.2015 12:55:27

Здравствуйте, Максим. Спасибо большое за ваш труд, очень познавательно и пригодилось в работе. Но столкнулась с одной неразрешимой (пока) задачей. Проблема: движок сайта генерирует дубли главной страницы по типу:
http://www.site.ru/index.php?lang=ru&subpage=182

Эти страницы попадают в индекс, что не есть хорошо. Естественно, я хочу перенаправить все подобные страницы на главную www.site.ru, но что-то не получается..
Один из последних опробованных методов:
RewriteCond %{QUERY_STRING} ^(.*)$ [NC]
RewriteRule ^index\.php?$ http://www.site.ru/ [R=301,L]

Такой код выдает 500 ошибку. Естественно, это не один вариант моих попыток, уже всего не упомню.

Не могли бы вы подсказать, где ошибка, куда смотреть.

Максим

04.03.2015 13:51:12

Олеся, вы забыли в правиле знак вопрос на конце, попробуйте так:

RewriteCond %{QUERY_STRING} ^(.+)$ [NC]
RewriteRule ^index.php$ /? [R=301,L]

Олеся

04.03.2015 14:00:55

Максим, огромнейшее вам спасибо! Все получилось!

Дмитрий

05.03.2015 15:26:30

Чтоб каждый раз не проверять в новом окне в режиме "инкогнито", лучше пойти сюда http://www.bertal.ru и смотреть заголовки там)

Михаил

16.03.2015 20:22:19

"Броузеры кешируют редиректы" - ОЧЕНЬ важное замечание, выделите в тексте, чтоб бросилось в глаза!!!
Полтора часа бился с редиректом, приводя его в тот вид который нужно, а он "сво" ведет себя совершенно одинаково!!! Увидел Ваше замечание, очистил кэш (вручную) - сразу все заработало!!!
Перелопатил половину рунета - только здесь это написано!!! Грандмерси!!! А сколько выкинутых в окно компов уже по всей России... )))))

Максим

17.03.2015 18:59:51

Михаил, спасибо, сделал надпись крупнее

Олеся

17.03.2015 19:18:49

Может, кому пригодится — для решения проблемы кеширования использую аддон: https://chrome.google.com/webstore/detail/open-in-incognito/peacnpgnojjkmbepjndigjojeoipkflb?utm_source=chrome-app-launcher-info-dialog

Алексей

22.03.2015 10:20:43

Добры вечер, Максим
Спасибо за статью. Вроде как всё написано понятно, доступно и просто, но мой сайт ни как не реагирует на мои попытки изменить htaccess, а именно хочу сделать ЧПУ, т.е. чтоб вместо catalog/05.htm отображалось /lenta. Файл htaccess лежит в корневом каталоге, но я его пробовал создавать и в других каталогах, но всё как-то безрезультатно, последнее из того, что я провал:
RewriteRule ^catalog/05.htm$ /lenta

Максим

22.03.2015 13:38:43

Алексей, возможно сервер не обрабатывает файлы .htaccess, попробуйте там написать ерунду, и если не получите 500-ю ошибку на сайте - значит точно не обрабатывает.

Это может происходить, если в конфигурационных файлах апача стоит запрет на переопределение параметров с помощью .htaccess:
AllowOverride None
нужно его заменить на
AllowOverride All

Либо сервер может работать на nginx, без апача вовсе, и тогда файлы .htaccess не имеют смысла.

Алексей

22.03.2015 15:45:13

Максим, я написал ерунду и получил в ответ ошибку "500 Internal Server Error"
получается что сервер всё же обрабатывает htaccess

Вот полный текст моего htaccess:
php_value session.use_trans_sid 0
php_value asp_tags on
php_value magic_quote_gpc off
php_value magic_quote_runtime off
php_value display_errors off
php_flag magic_quotes_gpc 0
RewriteEngine on

RewriteRule ^index.php - [L]

RewriteRule ^catalog/05.htm$ /lenta [L]

RewriteCond %{REQUEST_URI} !^/admin/
RewriteRule !\.(gif|css|jpg|zip|doc|js|txt|html|xls|ico)$ /index.php [L]

php_flag register_globals on

Максим

22.03.2015 17:58:21

Алексей, то как вы написали, приведет к тому, что если зайти на страницу "catalog/05.htm", то будет показана страница "lenta", но её у вас нет, и будет 404. Вам нужно наоборот:
RewriteRule ^lenta /catalog/05.htm [L,NS]

Алексей

22.03.2015 18:09:08

Максим, я попробовал, но всё равно выдаёт сообщение когда я ввожу http://www.site.ru/lenta/, что

Страница не найдена
Запрошенная Вами страница не существует.

Даже такой вариант попробовал, RewriteRule ^lenta$ /catalog/05.htm [L,NS]

Максим

22.03.2015 18:16:59

Алексей, ну например
http://www.site.ru/lenta/ - есть слеш на конце
RewriteRule ^lenta$ /catalog/05.htm [L,NS] - ^lenta$ лента ищется без слеша на конце

Также помните что браузеры кешируют редиректы, нужно проверять каждый раз в НОВОМ окне в режиме инкогнито, при этом закрывая предыдущее окно.

Максим

22.03.2015 19:28:54

К сожалению ветка комментариев к этой странице скатилась к малоинформативному флуду. Я удалил комментарии, которые не привносят полезной информации. И буду удалять в дальнейшем.

Цель страницы прояснить как можно больше вопросов по использованию файла .htaccess.

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

Алексей

22.03.2015 23:05:10

Максим, перепробовал и со / и без и всё ни как. Может необходимо скопировать файл htaccess в папке templates или catalog?

Максим

23.03.2015 08:10:09

Алексей, файл .htaccess с редиректами должен быть только в корне сайта, в директории DOCUMENT_ROOT. Копий в поддиректориях быть не должно.

Алексей2

23.03.2015 12:03:26

Максим, вы сетуете на то, что нет вопросов по использованию файла .htaccess. между тем мой комментарий остался без ответа. Ну, и есть путаница с именами авторов. У меня здесь один комментарий связанный с редиректом при отсутствующем файле.
Повторю код, который использую в .htaccess.
RewriteEngine on
RewriteBase /~quux/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule tema(.*)$ http://site.ru/forum/tema$1 [R=301,L]

Править приходится такой адрес
http://www.site.ru/forum/%0D%0Atema.php?t=хххх
Это адрес странички сайта. Адрес реальный, но идёт ошибка из-за врезки в адресе %0D%0A, которую делает робот Яндекса. Такая же врезка встречается в стринговой части адреса, но в этом случае сервер не отдаёт 404 ошибку и эту врезку я удаляю PHP скриптом.
Приведённый выше код .htaccess для преодоления 404 ошибки срабатывает не всегда, это следует из лог файла сайта. Стабильно предложенный выше код срабатывает при обновлении странички в браузере - почему так, не знаю, может срабатывают скрипты сайта и результат появляется при повторной загрузке сайта в браузер.

В общем, не получается решить эту задачку средствами .htaccess в самом .htaccess или преодолеть ответ сервера 404, чтобы в PHP избавится от %0D%0A в адресе странички.

Максим

23.03.2015 14:43:22

Алексей2, я думал вы решили проблему и поделились решением.

Я внимательно изучил вашу проблему, и я не знаю что можно тут сделать.

Символы %0D%0A кодируют конец строки и перевод каретки, апач перед проведениями манипуляции с адресами преобразует код в значения. Я попробовал на винде поэкспериментировать с данным адресом, на винде вообще апач не преобразовывает такие адреса, т.е. работает не корректно, в линуксе видимо по другому.

Немного по теме: Интересная проблема в .htaccess или спецсимволы, mod_rewrite и тег C++.

Когда решите вопрос. плиз напишите о решении.

Алексей2

23.03.2015 19:29:54

Максим, ссылка не по теме.
Там решается задача по редиректу без ошибок переменной tag, то есть существующего адреса. Тем не менее, предложенный вариант реализовал, но результат остался тот же, редирект происходит при повторном обращении по тому же адресу.
В моём случае адрес странички тоже реальный, но в адресе есть врезка с кодом, "подарок" от Яндекса. Сервер читает код врезки, а, может, и не весь код, после чего выдаёт ошибку 404. Я так понимаю, что этот код работает по аналогии со знаком "?", и всё, что после кода, сервер не интересует. В тоже время, при обновлении окна браузера редирект происходит, при этом, если 301 редирект, то зловредный код вырезается из конечного результата адреса странички.
Напрашивается вариант, сделать два подряд обращения к сайту по одному и тому же адресу.
Из файла ошибок следует, что сервер не нашёл файл и в этом файле код врезки %0D%0A заменён на \r\n.

Максим

23.03.2015 19:52:55

Алексей, я тоже понял что все что после кода сервер не понимает, ну логично, он увидел символ конца строки.

Вижу 2 варианта:

1. Искать модули апача, которые могут помочь, alias например, но я в этом вопросе не силен. Либо может у nginx нет такой проблемы. Этот вариант правильный, но трудоемкий.

2. Раз у вас апач отдает 404, значит он подключает скрипт для обработки отображенияя ошибки 404.php. А на пхп уже можно найти варианты где разгуляться. Но это увы костыль.

Алексей2

23.03.2015 20:56:06

Максим, у меня нет доступа к серверу.
На ПХП я бы сделал редирект, но мне не известен адрес, который ищет сервер на моём сайте. Тот, что находится в адресной строке браузера я уже весь перебрал, редиректа на ПХП нет.
Максим, спасибо за внимание. Очевидно, что решения задачки откладывается.
Будут новости, сообщу.

Виктор

24.03.2015 00:17:17

Максим, есть необходимость вырезать в сгенерированных движком сайта все запросы после "?". Конструкция:
RewriteCond %{QUERY_STRING} ^.+$ [NC]
RewriteRule (.*) /? [R=301,L]
вырезает их "на ура".
Но иногда генерируются пустые запросы типа http://site.ru/?
В этом случае такой редирект не срабатывает. Подскажите пожалуйста, как можно избавиться от знака вопроса в моем случае?
Заранее спасибо.

Максим

24.03.2015 06:31:15

Виктор, предлагаю искать знак вопроса в исходном запросе:
RewriteCond %{THE_REQUEST} \? [NC]
RewriteCond %{REQUEST_URI} (.*) [NC]
RewriteRule (.*) %1? [R=301,L]

Виктор

24.03.2015 10:21:10

Максим, помогло, большое спасибо!

Дима

24.03.2015 19:50:32

301 редирект для мультиязычного сайта на Joomla 3 c 303 редиректом

Здравствуйте, уважаемые!

Прошу помочь решить следующую насущную для мультиязычного сайта на Joomla 3 и, думаю, многих других CMS, проблему:
При создании нескольких языковых версий сайта средствами мультиязычности самой CMS получается следующее:
http://domain.ru -с русским языком
http://domain.ru/ru/-русская версия сайта(является основным языком сайта)
http://domain.ru/en/-английская версия сайта
http://domain.ru/de/-немецкая версия сайта
и если средствами Joomla 3 удалять префикс /ru/ из адресной строки, то срабатывает 303 редирект, что есть нехорошо, т.к. для SEO нужен 301 редирект.
Если же не убирать префикс в настройках Joomla 3, то будет существовать domain.ru/ru/ и domain.ru с русским языком, т.е. дубли.
Как посредством .htaccess убрать префикс /ru/, т.е. сделать 301 редирект с domain.ru/ru/ -> domain.ru и чтобы в последующем переключение языков на сайте было корректным.

В течение 2-x недель поиска информации в интернете опробовал разные куски кода в htaccess, но рабочего варианта так и не нашел.
Распишите, пожалуйста, подробно как решить эту проблему, т.к. с этим вопросом не могут справится куча народа, как в русскоязычном сегменте интернета, так и зарубежом, либо опишите другие возможные варианты решения. Если вам несложно, то вышлите мне решение на почту myhelpers@mail.ru , чтобы быстрее смог его реализовать.
Если для кого-то это тривиально, то простите за незнание! :-)

Алексей2

24.03.2015 22:15:08

Дима, решить вашу задачку за один ход не получиться.
Ну, а о том, как убрать /ru/ из адреса Максим написал выше. Для вашего случая правило будет такое

RewriteRule ^$ /ru/ [L]

В этом случае при адресе http://domain.ru на сайте будет подключаться русский язык. Если просто убрать /ru/ из адресной строки, то не сможете подключить русский язык.
Кроме этого, Потребуется создать аналогичное правило во всех директориях сайта и для всех файлов. Для роботов сделаете 301 редирект с http://domain.ru/ru/ на http://domain.ru или пропишите вначале страницы приоритет на URL.

Александр

28.03.2015 13:28:07

Добрый день, Максим! Прошу помощи. Новичок в этом деле. Опишу ситуацию. Есть домен и хостинг. Сайт не загружен. Можно ли с пустого домена сделать редирект на работающий бесплатный лендинг? Если можно, то как?

Станислав

28.03.2015 17:04:53

Здравствуйте, у меня такая проблемка, не знаю как быть, все варианты, которые перебирал на просторах интернета увенчались 500 ошибкой

редирект со страницы:
http://domen.ru/?view=str&id=123
на страницу:
http://domen.ru/?view=str&id=123&DOP_STROKA_CHPU

Спасибо за внимание

Игорь

31.03.2015 20:44:41

Здравствуйте.
А как убрать все что находится после html в конце урла?
Т.е. с такой страниці http://www.myfavoritegadgets.info/DonateUs.html/indexs.html
получить такую http://www.myfavoritegadgets.info/DonateUs.html
правда если есть #метка то ее нужно оставить. Как-то не выходит у меня. Спасибо

Олеся

10.04.2015 12:13:19

Здравствуйте!
У меня проблема появилась после написания правила редиреккта со страниц без .html на .html...

RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]+)$ /$1.html [R=301,L]
RewriteRule . /index.php [L]

Но теперь я не могу зайти в админку WP...

Подскажите пожалуйста, что нужно дописать?!

Здесь у меня ошибка в написании, но примерно это?!

RewriteCond %{REQUEST_URI} !^/wp-admin
RewriteCond %{REQUEST_URI} !^/wp-login.php$

Игорь

29.04.2015 16:03:34

Максим, помогите при возможности. Магазин установлен в директорию. В разделах каталога есть пагинация. Первая страница имеет вид:
сайт.ру/магазин/каталог/

Но она же доступна по
сайт.ру/магазин/каталог/?page=1


Как мне сделать 301 с /каталог/?page=1 на /каталог/

Спасибо заранее.

Александр

19.06.2015 19:19:45

Вроде бы не было такого вопроса. Максим помогите пожалуйста

есть урл вида
http://site.com/katalog/fasadnaya-plitka/podrazdel/feldhaus-classic/
Надо убрать два подкаталога katalog и podrazdel как быть ? Что бы получилось так

http://site.com/fasadnaya-plitka/feldhaus-classic/

Максим

20.06.2015 09:47:34

Игорь, Александр, в ваших задачах нет ничего сложного, в первом случае условие от гет параметра, во втором случае вообще обычный редирект c подстановками:

RewriteRule /katalog/(.*)/podrazdel/(.*)/ /$1/$2/[R=301,L]
#пример на работоспособность не проверял

PS Цель данной страницы не решать чужие задачи, а показать принцип работы правил в htaccess

Иван Пи

20.06.2015 21:06:07

Перелопатил кучу статей на эту тему - эта самая лучшая!!! Большое СПАСИБО!

Дмитрий

23.06.2015 03:28:07

Максим здравствуйте, подскажите пжл как сделать редирект со всеми страницами, пример:

http://www.sait.com/index.php?name=news&op=view&id=6565
на
http://www.sait.com/news-view-6565.html

Андрей

28.06.2015 14:17:23

Спасибо, за наводку о кешировании редиректов в браузере !
пол дня просидел, пока в другом браузере не проверил ))

Андрей

30.06.2015 23:50:00

Максим, подскажите пожалуйста:

есть работающее правило:
RewriteCond %{QUERY_STRING} (.*(?:^|&))filter=%26fd13%3D106((?:&|$).*) [NC]
RewriteRule ^kedyi-krossovki(.*)$ /kedyi-krossovki/dlya_devochek/? [R=301,L]

а нужно сделать универсальное, чтобы работало при любой подстроке вместо kedyi-krossovki, т.е. по сути надо при выполнении условия по параметру просто добавить в конец вызываемого URL еще один подкаталог, не стирая те, что уже были.
Пол-интернета перерыл - везде примеры в которых отбрасывается все после корня и потом добавляется подкаталог, а мне не нужно отбрасывать то, надо только добавить...

Андрей

01.07.2015 00:00:27

Пробую вот так:
RewriteCond %{QUERY_STRING} (.*(?:^|&))filter=%26fd13%3D105((?:&|$).*) [NC]
RewriteRule /(.*)/(.*)/ /$1/$2/dlya_malchikov/? [R=301,L]

Но, во-первых, это не работает почему то, во-вторых, подкаталогов неизвестно сколько в исходном адресе может быть, поэтому /$1/$2 не вариант, их может быть >2 , и надо только добавить в конец еще один

Антон

08.07.2015 14:07:33

Всем привет. никак не осилить.
Мне надо написать .htaccess со следующими правилами:

1. Что - бы не было введено в url обрабатывался index.php который лежит в корне
2. Получать переменные GET и POST безпроблемно.

Весь разбор url я веду в index.php
Вроде все просто, но потратил уже полдня - не даются мне эти конструкции.

Александр

10.07.2015 12:15:44

Здравствуйте!

Один редирект перебивает другой. Подскажите пожалуйста, как сделать, чтобы он разделы тоже брал в расчет ?

#Redirect 301 /presents/?tag=decoration /catalog/podarki/prazdnik-gifts/podarki-novyy-god/
RewriteCond %{QUERY_STRING} tag=decoration [NC]
RewriteRule .* /catalog/podarki/prazdnik-gifts/podarki-novyy-god/? [R=301,L]

#Redirect 301 /partystuff/?tag=decoration /holidays/
RewriteCond %{QUERY_STRING} tag=decoration [NC]
RewriteRule .* /holidays/? [R=301,L]

Александр

10.07.2015 16:45:43

Сам отвечу, вдруг кому пригодится.
Дописываем правило перед tag=decoration :
RewriteCond %{REQUEST_URI} ^/partystuff/ [NC]

Александр

23.07.2015 22:31:06

Не подскажете как решить задачу? Есть зарегистрированный домен www.borya.ru Нужно, чтобы при наборе этого адреса в браузере открывалась страница, расположенная на сайте с другим именем. Ну, к примеру:
Страница есть на сайте www.vasja.ru/borya/index.html
То есть нужно упростить этот адрес до www.borya.ru Как это сделать? Совсем запутался:)

Георгий

24.07.2015 20:45:43

универсальный код сработал
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteCond %{HTTP_USER_AGENT} (?i:midp|samsung|nokia|j2me|avant|docomo|novarra|palmos|palmsource|opwv|chtml|pda|mmp|blackberry|mib|symbian|wireless|nokia|hand|mobi|phone|cdm|upb|audio|SIE|SEC|samsung|HTC|mot-|mitsu|sagem|sony|alcatel|lg|eric|vx|NEC|philips|mmm|xx|panasonic|sharp|wap|sch|rover|pocket|benq|java|pt|pg|vox|amoi|bird|compal|kg|voda|sany|kdd|dbt|sendo|sgh|gradi|jb|dddi|moto|iphone|android) [NC]
RewriteRule ^$ /m/ [R=302,L]

Но как теперь сделать чтобы не только index.html редиректил на /m/index.html
но и остальные about.html перенаправлялись на /m/about.html

Максим

25.07.2015 19:15:32

Георгий, измените последнюю строку:
RewriteRule ^(.*)$ /m/$1 [R=302,L]

георгий

26.07.2015 08:54:24

Пишет множественный редирект

Максим

26.07.2015 09:03:35

а, ну конечно:),
попробуйте так:

RewriteCond %{HTTP_USER_AGENT} (?i:midp|samsung|nokia|j2me|avant|docomo|novarra|palmos|palmsource|opwv|chtml|pda|mmp|blackberry|mib|symbian|wireless|nokia|hand|mobi|phone|cdm|upb|audio|SIE|SEC|samsung|HTC|mot-|mitsu|sagem|sony|alcatel|lg|eric|vx|NEC|philips|mmm|xx|panasonic|sharp|wap|sch|rover|pocket|benq|java|pt|pg|vox|amoi|bird|compal|kg|voda|sany|kdd|dbt|sendo|sgh|gradi|jb|dddi|moto|iphone|android) [NC]
RewriteCond %{REQUEST_URI} !^m
RewriteRule ^(.*)$ /m/$1 [R=302,L]

Георгий

26.07.2015 10:40:01

все равно /m/m/m/m/m/m/m/

Вот мой файл


<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]

RewriteCond %{HTTP_USER_AGENT} (?i:midp|samsung|nokia|j2me|avant|docomo|novarra|palmos|palmsource|opwv|chtml|pda|mmp|blackberry|mib|symbian|wireless|nokia|hand|mobi|phone|cdm|upb|audio|SIE|SEC|samsung|HTC|mot-|mitsu|sagem|sony|alcatel|lg|eric|vx|NEC|philips|mmm|xx|panasonic|sharp|wap|sch|rover|pocket|benq|java|pt|pg|vox|amoi|bird|compal|kg|voda|sany|kdd|dbt|sendo|sgh|gradi|jb|dddi|moto|iphone|android) [NC]
RewriteCond %{REQUEST_URI} !^m
RewriteRule ^(.*)$ /m/$1 [R=302,L]

</IfModule>

Максим

26.07.2015 16:26:00

RewriteCond %{REQUEST_URI} !^/m

PS проверить негде, пишу на коленке.

Георгий

26.07.2015 17:28:22

Сам промучался два дня с .htaccessom/
В итоге сделал все на js/
Все прекрасно работает.
Спасибо Максим

роман

07.08.2015 23:16:17

как сделать чтобы с десктопа нельзя было открыть мобильную версию ?

Алексей2

15.08.2015 23:09:30

Максим, вопрос по редиректу адреса странички
http://www.site.ru/forum/%0D%0Atema.php?t=хххх
со врезкой постороннего кода (см. выше), закрыт. Результат отрицательный. Длительная переписка с хостером не дала результата. Они всё проверяли правильность редиректа, сделанного мною.
В тоже время, были адреса со врезкой постороннего кода в этом же месте адресной строки, но код врезки был другой, и результат редиректа был положительный. В общем, всё дело в сервере, который зависает на этом коде врезки в адресную строку, при этом выдаёт ещё ложное сообщение о 404 ошибке. Ложную, потому что я не могу по 404 ошибке перейти на свою страничку 404, редирект не работает в данном случае.

Лия

04.09.2015 20:58:19

Здравствуйте! Подскажите пожалуйста что можно сделать с файлом .htaccess, хотела настроить его перед переносом на хостинг, но теперь показывает на всех страницах 404 ошибку, попробовала удалить файл, закинула старый , но результата ноль,провобала вернуть htaccess.txt, почистила кэш, настраивала в админке SEO, но опять тоже самое, возможно ли восстановить сайт? Я в этом новичок, это мой первый сайт, приходиться самой разбираться и искать все в нете :)

Options +FollowSymLinks -Indexes

AddDefaultCharset utf-8


<IfModule mod_rewrite.c>

RewriteEngine On

RewriteBase /

RewriteCond %{THE_REQUEST} !^POST

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/

RewriteCond %{SERVER_PORT}>s ^(443>(s)|[0-9]+>s)$

RewriteRule ^index\.php$ http%2://site.ru/ [R=301,L]

RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]

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

</IfModule>


DirectoryIndex index.php


RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]

RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]

RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]

RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})


RewriteRule .* index.php [F]


RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]


RewriteCond %{REQUEST_URI} !^/index\.php

RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule .* index.php [L]

Строки ниже, отвечают за блокирование MySQL инъекций:

RewriteCond %{query_string} concat.*\( [NC,OR]

RewriteCond %{query_string} uni on.*select.*\( [NC,OR]

RewriteCond %{query_string} union.*all.*sel ect [NC]

RewriteRule ^(.*)$ index.php [F,L] 

Код отвечающий за блокировку файловых инъекций:

<code>RewriteCond %{REQUEST_METHOD} GET<code>
<code>RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR]<code>
<code>RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR]<code>
<code>RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC]<code>
<code>RewriteRule .* - [F]<code>

Максим

05.09.2015 18:48:31

Лия, скорее всего ошибка 404 из-за того что файл .htaccess не работает.
Вы пишете что вернули файл "htaccess.txt" - это не правильное название, он должно называться именно ".htaccess"
Т.е. файл без названия с расширением htaccess
В винде штатно такой не сделать, нужно использовать файловые менеджеры типа фара или тотал коммандера

Лия

06.09.2015 14:19:58

Максим, Благодарю за ответ. Это тоже пробовала, выложила старую копию на сервер кое как настроила. А на локальном так и не работает. Я пробую на шаблона yoo nano, поналепила во все папки заглушку index. html, может ли быть из за этого? Так и не пойму везде его надо вставлять или нет?

Евгений Е.

07.09.2015 18:02:48

Большое спасибо за статью. Если не трудно, подскажите как реализовать отдачу backend'a и frontend'a на разные домены. Оба домена привязаны к одному сайту.
У этого сайта, в DocumentRoot, есть папки backend/ и frontend/
Есть домен site.ru который должен отдавать контент из папки frontend/web и есть домен третьего уровня admin.site.ru, который должен отдавать содержимое backend/web

Нашел решение для одного домена с подпапкой /admin и попытался переделать под свои цели, но неуспешно. Что может быть не так?


RewriteCond %{HTTP_HOST} ^admin\.(.*)$
RewriteRule (.*) /backend/web/$1

RewriteCond %{REQUEST_URI} !^/(frontend/web|backend/web)
RewriteRule (.*) /frontend/web/$1

RewriteCond %{REQUEST_URI} ^/frontend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /frontend/web/index.php

RewriteCond %{REQUEST_URI} ^/backend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /backend/web/index.php

Евгений Е.

07.09.2015 18:08:23

Делал еще вот так (первые две строки):

RewriteCond %{HTTP_HOST} ^(admin\..*)
RewriteRule (.*) http://%1/backend/web/$1

Ответ:
Found

The document has moved here.

Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.

Иван

07.09.2015 21:13:25

День добрый. Подскажите, есть ли более удобное
решение для 301 редиректа всех страниц каталога
www.site.ru/dir/[a-zA-Z0-9_] в каталог www.site.ru/dir

Кроме как прописать вручную все страницы:
Redirect 301 /dir/vla_s http://www.site.ru/dir
Redirect 301 /dir/sk_ar http://www.site.ru/dir
Redirect 301 /dir/ope_n http://www.site.ru/dir
Redirect 301 /dir/l_ico http://www.site.ru/dir

игорь

08.09.2015 04:48:12

Подскажите есть страницы http://www.site.ru/slink.php?link=12/ http://www.site.ru/link.php?link=49/ как убрать слеш в конце url

Кондратьев Владимир Васильевич

28.05.2020 14:09:56

У меня проблема. В корне проекта .htaccess:
AddDefaultCharset utf-8
RewriteEngine on
RewriteBase /
Options All -Indexes
RewriteRule ^(.*)$ /public/$1
RewriteRule ^resource/(.*)$ resource/$1 [L]

В папке public .htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?$1 [L,QSA],

а index.php вызывает index.html из папки page.

index.html не видит CSS файлы из папки <корень>\resource,
хотя в самом index.html ссылки к ним по link нормально разрешены,
как видно в PhpStorm. Не поможете обяснить это?

Кондратьев Владимир Васильевич

28.05.2020 14:29:36

У меня проблема. В корне проекта .htaccess:
AddDefaultCharset utf-8
RewriteEngine on
RewriteBase /
Options All -Indexes
RewriteRule ^(.*)$ /public/$1
RewriteRule ^resource/(.*)$ resource/$1 [L]

В папке public .htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?$1 [L,QSA],

а index.php вызывает index.html из папки page.

index.html не видит CSS файлы из папки <корень>\resource,
хотя в самом index.html ссылки к ним по link нормально разрешены,
как видно в PhpStorm. Не поможете обяснить это?

Максим

28.05.2020 15:07:04

Вернул возможность комментировать на этой странице, но разбирать почему у кого что не работает я не имею возможности, нет времени.
Надеюсь на понимание, всем Спасибо!

Кондратьев Владимир Васильевич

29.05.2020 12:57:11

Конечно интересно общаться с Вашим почтовым роботом, но просмотрите почту сами.

Кондратьев Владимир Васильевич

29.05.2020 13:03:31

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

Алексей

21.07.2020 09:33:11

Подскажите, пожалуйста, а как правильно прописать, чтобы в адресной строке браузера адрес

https://promo.gorod.ru/browse?locationType=address&city=524901

заменить на

https://promo.gorod.ru/moscow

Оставить комментарий:

Представьтесь пожалуйста:
Электронная почта:
Электронный адрес не публикуются
Текст сообщения:
Для подсветки кода, оборачивайте ваш код в теги <code></code>
Введите 5 цифр с картинки:

Рекомендую:

Поделюсь промокодами для хостинга TimeWeb!

Поддержать проект: