Страницы

Поиск по вопросам

Показаны сообщения с ярлыком mod-rewrite. Показать все сообщения
Показаны сообщения с ярлыком mod-rewrite. Показать все сообщения

среда, 4 марта 2020 г.

Как сделать ЧПУ через .htaccess или другим способом

#htaccess #apache #mod_rewrite


Здравствуйте, подскажите как сделать ЧПУ через .htaccess или другим способом. На
данный момент пытаюсь реализовать через .htaccess, но что-то не так.

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

Вот .htaccess

RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} !=on 
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteRule ^([a-z]+)/([a-z]+)/$ ?country=$1®ion=$2&city=$3 [QSA,L]
RewriteRule .* index.php [L]

    


Ответы

Ответ 1



Если у вас уже единая точка входа (это хорошо) и нет зависимости от .htaccess (это хорошо), то не надо добавлять зависимость от .htaccess и терять достоинства единой точки входа: весь роутинг в одном месте, независимость от сервера. Разбирайте ваш URL прямо в index.php. Подробнее: Как сделать всё и сразу в mod_rewrite? P. S. Не могу закрыть как дубликат вопрос под конкурсом. P. P. S. Уже ничего не помню про .htaccess, но в вашем коде, вроде, проблема в том, что все преобразования повешены на одно условие.

Ответ 2



.htaccess проходится повторно, если были изменения строки запроса условиями. Осторожнее с .* иначе все запросы будут попадать именно туда. Можно использовать [END] для остановки повторного прохода. [L] останавливает парсинг, но не отменяет повторный проход

понедельник, 24 февраля 2020 г.

Как прописать редирект в .htaccess если изменился домен?

#htaccess #redirect #домен #mod_rewrite #поддомены


Есть старый сайт на поддомене, например 2015.site.ru

поменяли основной домен site.ru на 2015.site.moscow

теперь нужно чтобы все обращения к 2015.site.ru переадресовывались на 2015.site.moscow

И естественно, не только обращения только к инденсу домена, но и любые другие, например
чтобы http://2015.site.ru/images/pic.gif преобразовывался в http://2015.site.moscow/images/pic.gif

Однако при обращение к основному сайту site.ru не должно быть переадресации на site.moscow
Подскажите пожалуйста, как такое прописать в .htaccess?
    


Ответы

Ответ 1



просто классика. скопировано из ответа: rewriteengine on rewritecond %{HTTP_HOST} ^a\.example\.com rewriterule ^(.*)$ http://b.example.com/$1 [r,l] доп. информация: http://wiki.apache.org/httpd/WhenNotToUseRewrite

Ответ 2



Если ограничиваться только протоколом HTTP, то необходимый редирект можно записать, например, так: RewriteEngine On RewriteCond %{HTTP_HOST} ^2015\.site\.ru$ RewriteRule ^(.*)$ http://2015.site.moskow/$1 [R=301,L] Если надо таким же образом перенаправлять и протокол HTTPS, то правило будет немного посложнее: RewriteEngine On RewriteCond %{HTTP_HOST} ^2015\.site\.ru$ [NC] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ http://2015.site.moskow/$1 [R=301,L] RewriteCond %{HTTP_HOST} ^2015\.site\.ru$ [NC] RewriteCond %{HTTPS} on RewriteRule ^(.*)$ https://2015.site.moskow/$1 [R=301,L] Это правило понятно, но избыточно и сделано слишком прямолинейно. Можно его оптимизировать, убрав повторяющиеся элементы. В результате получится следующее: RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ - [env=protocol:http] RewriteCond %{HTTPS} on RewriteRule ^(.*)$ - [env=protocol:https] RewriteCond %{HTTP_HOST} ^2015\.site\.ru$ [NC] RewriteRule ^(.*)$ %{ENV:protocol}://2015.site.moskow/$1 [R=301,L] Интересно, что мне не удалось найти онлайн-тестер файла .htaccess, понимающий последний вариант. Но "живой" Apache обработал его корректно.

пятница, 24 января 2020 г.

Как делать перенаправление с site.ru/ на site.ru/ru/

#php #htaccess #mod_rewrite


Как делать перенаправление с site.ru/ на site.ru/ru/

Пробовал так:

RewriteRule ^(.*)/$ /ru/ [L]


Выдает ошибку 500

А так:

RewriteRule ^(.*)/$ /ru/ [R=301,L]


Ругается что переадресацию много раз делаю
    


Ответы

Ответ 1



чтоб не было циклической переадресации, можно проверять, что url не начинается с /ru/ RewriteCond %{REQUEST_URI} !^/ru/ RewriteRule ^(.*)$ /ru/$1 [R=301,L]

Ответ 2



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

суббота, 7 декабря 2019 г.

Редирект url на нижний регистр

#htaccess #apache #mod_rewrite


Подскажите, как корректно настроить через файл .htaccess 301 редирект на нижний регистр
ссылок в таком рЕгИсТре?
Спасибо!
    


Ответы

Ответ 1



На одном из проектов ставил в htaccess 2 правило отсюда, но сейчас опробовал и первый вариант: Добавляем в файл виртуального хоста запись: RewriteMap lc int:tolower После чего, добавляем следующие записи в .htaccess: RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} ^[^A-Z]*[A-Z].* RewriteRule ^ ${lc:%{REQUEST_URI}} [L,R=301] Второй вариант подобный правил: RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} [A-Z] RewriteRule (.*) ${lc:$1} [R=301,L] Способ 2 — наиболее громоздкий, но не требующий доступа к настройкам Apache. Достаточно добавить правила в .htaccess: RewriteEngine On RewriteBase / # If there are caps, set HASCAPS to true and skip next rule RewriteRule [A-Z] - [E=HASCAPS:TRUE,S=1] # Skip this entire section if no uppercase letters in requested URL RewriteRule ![A-Z] - [S=28] # Replace single occurance of CAP with cap, then process next Rule. RewriteRule ^([^A]*)A(.*)$ $1a$2 RewriteRule ^([^B]*)B(.*)$ $1b$2 RewriteRule ^([^C]*)C(.*)$ $1c$2 RewriteRule ^([^D]*)D(.*)$ $1d$2 RewriteRule ^([^E]*)E(.*)$ $1e$2 RewriteRule ^([^F]*)F(.*)$ $1f$2 RewriteRule ^([^G]*)G(.*)$ $1g$2 RewriteRule ^([^H]*)H(.*)$ $1h$2 RewriteRule ^([^I]*)I(.*)$ $1i$2 RewriteRule ^([^J]*)J(.*)$ $1j$2 RewriteRule ^([^K]*)K(.*)$ $1k$2 RewriteRule ^([^L]*)L(.*)$ $1l$2 RewriteRule ^([^M]*)M(.*)$ $1m$2 RewriteRule ^([^N]*)N(.*)$ $1n$2 RewriteRule ^([^O]*)O(.*)$ $1o$2 RewriteRule ^([^P]*)P(.*)$ $1p$2 RewriteRule ^([^Q]*)Q(.*)$ $1q$2 RewriteRule ^([^R]*)R(.*)$ $1r$2 RewriteRule ^([^S]*)S(.*)$ $1s$2 RewriteRule ^([^T]*)T(.*)$ $1t$2 RewriteRule ^([^U]*)U(.*)$ $1u$2 RewriteRule ^([^V]*)V(.*)$ $1v$2 RewriteRule ^([^W]*)W(.*)$ $1w$2 RewriteRule ^([^X]*)X(.*)$ $1x$2 RewriteRule ^([^Y]*)Y(.*)$ $1y$2 RewriteRule ^([^Z]*)Z(.*)$ $1z$2 # If there are any uppercase letters, restart at very first RewriteRule in file. RewriteRule [A-Z] - [N] RewriteCond %{ENV:HASCAPS} TRUE RewriteRule ^/?(.*) /$1 [R=301,L]

Ответ 2



Решение через PHP: if ( $_SERVER['REQUEST_URI'] != strtolower( $_SERVER['REQUEST_URI']) ) { header('Location: http://'.$_SERVER['HTTP_HOST'] . strtolower($_SERVER['REQUEST_URI']), true, 301); exit(); }

Ответ 3



if ( $_SERVER['REQUEST_URI'] != strtolower( $_SERVER['REQUEST_URI']) ) { header('Location: //'.$_SERVER['HTTP_HOST'] . strtolower($_SERVER['REQUEST_URI']), true, 301); exit(); } Лучше использовать "//" после Location вместо "http://". Это сделает выбор протокола автоматическим и предотвратит от двойной переадресации, если на сервере она настроена с http на https.

вторник, 16 июля 2019 г.

.htaccess редирект средствами mod_rewrite

На сайте использую ЧПУ. Пример:
RewriteRule ^index$ index.php RewriteRule ^index/$ index.php
В итоге, в адресную строку можно легко вводить такой адрес http://site.ru/index. Но вот незадача. Как теперь сделать так, чтобы ссылка типа http://site.ru/index.php стала недоступной, а доступ ко странице index.php мог бы осуществлять только по адресу http://site.ru/index?


Ответ

Ваши два правила легко можно объединить в одно, взяв слеш в квадратные скобки и написав после них знак вопроса - это сделает его "необязательным" символом, который может быть, а может не быть.
По сути вопроса - например, так:
RewriteRule ^index[/]?$ index.php [L,E=ACCESS_ALLOWED:1] RewriteCond %{REQUEST_URI} ^/index.php$ RewriteCond %{ENV:REDIRECT_ACCESS_ALLOWED} ^$ RewriteRule ^index.php$ - [F]
Что тут происходит: первая строчка дублирует Ваши правила из вопроса, с той разницей, что при перенаправлении с index на index.php устанавливает переменную окружения ACCESS_ALLOWED со значением 1. Имя переменной можно выбрать произвольно - она не имеет значения для Apache, и нужна нам только в этих правилах.
Во второй и тертьей строчке задаются два условия: "запрошен URI index.php" и "значение переменной окружения ACCESS_ALLOWED пусто". В последней строчке запрещается доступ к index.php
Как это работает: при запросе index или index/ происходит перенаправление на index.php с установкой переменной ACCESS_ALLOWED, равной 1. Условие о пустой переменной ACCESS_ALLOWED, соответственно, не срабатывает, и обусловленное этим правило о запрете доступа к index.php не выполняется. При запросе же index.php напрямую переменная ACCESS_ALLOWED оказывается не установленной, условие о её пустоте срабатывает, и обусловленное им правило о запрете доступа к index.php выполняется. В итоге по запросу index попасть на index.php можно, а по "прямому" запросу index.php - нет.
Можно, на самом деле, поступить ещё изящнее: вместо запрета доступа "напрямую" к index.php просто перебрасывать такие запросы HTTP-редиректом на "рекомендуемый" index/, сделать это можно вот так:
RewriteRule ^index[/]?$ index.php [L,E=ACCESS_ALLOWED:1] RewriteCond %{REQUEST_URI} ^/index.php$ RewriteCond %{ENV:REDIRECT_ACCESS_ALLOWED} ^$ RewriteRule ^index.php$ index/ [L,R=301]
Такая схема с 301-м редиректом полезна, когда у вас на сайте изменились адреса страниц, и есть задача "обучить" новым адресам поисковые системы, но не хочется терять трафик, идущий со старых ссылок на старые адреса.

понедельник, 20 мая 2019 г.

Как сделать ЧПУ через .htaccess или другим способом

Здравствуйте, подскажите как сделать ЧПУ через .htaccess или другим способом. На данный момент пытаюсь реализовать через .htaccess, но что-то не так.
Ситуация такая что использую одну точку входа через index.php, может это как-то влияет.
Вот .htaccess
RewriteEngine On RewriteBase / RewriteCond %{HTTPS} !=on RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteRule ^([a-z]+)/([a-z]+)/$ ?country=$1®ion=$2&city=$3 [QSA,L] RewriteRule .* index.php [L]


Ответ

Если у вас уже единая точка входа (это хорошо) и нет зависимости от .htaccess (это хорошо), то не надо добавлять зависимость от .htaccess и терять достоинства единой точки входа: весь роутинг в одном месте, независимость от сервера.
Разбирайте ваш URL прямо в index.php.
Подробнее: Как сделать всё и сразу в mod_rewrite?
P. S. Не могу закрыть как дубликат вопрос под конкурсом.
P. P. S. Уже ничего не помню про .htaccess, но в вашем коде, вроде, проблема в том, что все преобразования повешены на одно условие.

пятница, 10 мая 2019 г.

Как прописать редирект в .htaccess если изменился домен?

Есть старый сайт на поддомене, например 2015.site.ru
поменяли основной домен site.ru на 2015.site.moscow
теперь нужно чтобы все обращения к 2015.site.ru переадресовывались на 2015.site.moscow
И естественно, не только обращения только к инденсу домена, но и любые другие, например чтобы http://2015.site.ru/images/pic.gif преобразовывался в http://2015.site.moscow/images/pic.gif
Однако при обращение к основному сайту site.ru не должно быть переадресации на site.moscow Подскажите пожалуйста, как такое прописать в .htaccess?


Ответ

просто классика. скопировано из ответа
rewriteengine on rewritecond %{HTTP_HOST} ^a\.example\.com rewriterule ^(.*)$ http://b.example.com/$1 [r,l]

доп. информация: http://wiki.apache.org/httpd/WhenNotToUseRewrite

понедельник, 1 октября 2018 г.

Как сделать всё и сразу в mod_rewrite?

Я пишу сайт на PHP, использую сервер Apache. Мне надо сделать редирект с адреса www, человекочитаемые URL, редирект на канонический URL, мультиязычность, запретить некоторые юзер-агенты, забанить пользователей по IP и ещё много чего с помощью mod_rewrite, причём чтобы всё это настраивалось через админку.
Как мне это сделать?


Ответ

Вы идёте неправильным путём. Если делать всё через mod_rewrite, то вы столкнётесь с кучей проблем:
Вы погрязнете в тоннах нечитаемого и неподдерживаемого кода. Этот язык не предназначен для сложной логики, хоть он и условно полон по Тьюрингу. Вы намертво прибьёте свой сайт гвоздями к серверу Apache. Если вы захотите воспользоваться nginx, то у вас возникнут серьёзные проблемы. Отлаживать правила практически невозможно. Если вы столкнётесь с багом, который не исправляется пристальным взглядом на код, то искать ошибку будет сложно. Если у вас редактируемые через админку правила (человекочитаемые URL, забаненные диапазоны IP и т. п.), то программно редактировать .htaccess будет проблематично.
В современных фреймворках и CMS повсеместно используется роутинг через фронт-контроллер. Вот всё, что вам нужно:
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?_route=$1 [L,QSA]
Теперь в index.php вы будете иметь путь в $_GET['_route'], также сохранятся все остальные параметры в запросе GET. Вы можете писать какую вам угодно логику на языке, который вы хорошо знаете и понимаете, используя любые средства вроде доступа к конфигу для получения настроек роутинга и доступа к базе для получения забаненных диапазонов IP.
Если вас не смущает доступ к пути через $_SERVER['REQUEST_URI'] вместо $_GET['_route'], то вы можете упростить .htaccess ещё больше, как указано в примечаниях к другому ответу:
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L,QSA]
P. S. Канонические URL обычно достаточно указать в мета-информации страницы. Редиректы из-за отсутствия / в конце лишь впустую тратят ресурсы.