Перенаправление всех страниц, кроме одной, на главную через .htaccess

28 апр. 2016 г., 18:10:13
Просмотры: 31.3K
Голосов: 1

Я только что преобразовал старый веб-сайт в одностраничный WordPress.

На старом сайте было несколько URL-адресов, теперь есть только 1: главная страница. Плюс еще одна страница с политикой конфиденциальности.

Поэтому я хотел бы перенаправить все URL-адреса, кроме того, который имеет slug "privacy", на главную страницу.

Вот что я пытаюсь сделать, но безуспешно:

#пользовательские перенаправления
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/privacy-policy/
RewriteRule (.*) http://www.mywebsite.com/$1 [R=301,L]
</IfModule>

# BEGIN WordPress (стандартные правила wp htaccess)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Происходит слишком много перенаправлений: все URL бесконечно перенаправляются сами на себя, почему?

было бы лучше (если возможно) использовать правило redirect вместо rewrite?

ОБНОВЛЕНИЕ

следуя предложениям из комментариев, я попробовал следующие пользовательские перенаправления (перед стандартными правилами WP):

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/privacy-policy$
RewriteRule (.*) http://mywebsite.com/ [R=301,L]
</IfModule>

Но всё равно не работает

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

вероятно, именно это делает $1 ;)

Mark Kaplun Mark Kaplun
28 апр. 2016 г. 18:15:00

RewriteCond %{REQUEST_URI} !^/privacy-policy$ попробуйте этот вариант

Owais Alam Owais Alam
28 апр. 2016 г. 18:30:12

попытался убрать $1, как предложил @MarkKaplun, тот же результат

bluantinoo bluantinoo
28 апр. 2016 г. 18:47:07

@OwaisAlam Я тоже попробовал твой совет, но всё равно не работает

bluantinoo bluantinoo
28 апр. 2016 г. 18:47:25
Все ответы на вопрос 2
0

Проблемы

Получаю слишком много редиректов: все URL бесконечно перенаправляют сами на себя, почему?

Правила перезаписи Apache обрабатываются сверху вниз, поэтому ваше пользовательское правило перезаписи всегда выполняется первым. Флаг перенаправления R указывает Apache сообщить браузеру выполнить новый запрос к изменённому URL вместо обслуживания цели перезаписи по текущему адресу, а флаг L ("last") говорит Apache игнорировать все последующие правила перезаписи. Таким образом, когда применяется ваше RewriteRule, создаётся новый запрос и ваши правила снова обрабатываются с самого начала.

Ваше RewriteCond указывает Apache обрабатывать последующее RewriteRule, когда путь URI запроса не начинается с /privacy-policy - поэтому практически каждый запрос приводит к перенаправлению до того, как другие правила в вашем .htaccess могут быть хоть как-то оценены.

Как намекнул @MarkKaplun в комментариях, $1 - это обратная ссылка, которая заменяется частью совпавшего URI, содержащейся в первой "группе захвата" (первый набор скобок в шаблоне). Поскольку .* буквально совпадает с любым количеством любых символов, в вашем RewriteRule $1 заменяется всем путём URI.

По сути, ваши правила перезаписи:

RewriteCond %{REQUEST_URI} !^/privacy-policy/
RewriteRule (.*) http://www.mywebsite.com/$1 [R=301,L]

означают "Если URI не начинается с /privacy-policy/, заставить веб-браузер отправить новый запрос к http://www.mywebsite.com/(исходный путь URI)".

Для наглядности, предположим, вы перешли на http://www.mywebsite.com/blog/2015; вот что происходит с каждым запросом:

  1. /blog/2015 не начинается с /privacy-policy/, сказать браузеру перейти на http://www.mywebsite.com/blog/2015.
  2. /blog/2015 не начинается с /privacy-policy/, сказать браузеру перейти на http://www.mywebsite.com/blog/2015.
  3. /blog/2015 не начинается с /privacy-policy/, сказать браузеру перейти на http://www.mywebsite.com/blog/2015.
  4. [...]

Удаление обратной ссылки $1 из RewriteRule недостаточно, так как путь URI / (или просто пустой) всё равно не соответствует началу с /privacy-policy/, что приводит к такому поведению:

  1. /blog/2015 не начинается с /privacy-policy/, сказать браузеру перейти на http://www.mywebsite.com/.
  2. / не начинается с /privacy-policy/, сказать браузеру перейти на http://www.mywebsite.com/.
  3. / не начинается с /privacy-policy/, сказать браузеру перейти на http://www.mywebsite.com/.
  4. [...]

Вы можете проверить это поведение, посмотрев файлы журналов вашей установки Apache.


Решение

Если вы не планируете использовать стандартную маршрутизацию адресов WordPress, нет смысла оставлять стандартные правила перезаписи и добавлять новые поверх них. Настройте их под свои нужды вместо добавления сложности:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(/|index\.php)$ /index.php? [L]
RewriteRule ^/?privacy-policy/?$ /index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /? [L,R=301]
</IfModule>

Вкратце:

  1. .

    RewriteRule ^(/|index\.php)$ /index.php? [L]

    Если запрошены / или index.php, обслуживать index.php, но отбросить строку запроса (чтобы предотвратить изменение страниц через манипуляции с переменными запроса) и остановить обработку перезаписей.

  2. .

    RewriteRule ^/?privacy-policy/?$ /index.php [L]

    Если запрошен privacy-policy (с ведущим или завершающим слешем или без), обслуживать index.php и остановить обработку перезаписей.

  3. .
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /? [L,R=301]
    

    Если запрошенное имя файла не является файлом и не является директорией, совпасть с любым одиночным символом где угодно (чтобы применить правило независимо от URI) и сказать браузеру сделать новый запрос на /, отбросив строку запроса. Остановить обработку перезаписей.

Стоит отметить, что ваша задуманная логика, вероятно, вызовет множество неожиданных поведений - например, вы, скорее всего, не сможете получить доступ к административной панели. Также могут сломаться вложения. Но вышеприведённое как минимум даст хорошую отправную точку для изучения директив перезаписи.

29 апр. 2016 г. 08:32:57
2

Попробуйте следующий код:

<IfModule mod_rewrite.c>
RewriteRule ^/privacy-policy/? privacy-policy [L,NC]

RewriteCond %{HTTP_HOST} ^(www\.)?oldsite\.com  [NC]
RewriteRule ^ http://mywebsite.com%{REQUEST_URI} [NE,R=301,L]
</IfModule>
28 апр. 2016 г. 19:05:30
Комментарии

спасибо @florian, но все еще не работает, он продолжает перенаправлять на ту же самую страницу, которую я пытаюсь открыть. Независимо от URL, он бесконечно перенаправляет сам на себя. PS: зачем расширение ".html"?

bluantinoo bluantinoo
28 апр. 2016 г. 20:26:26

Извините, расширение '.html' действительно устарело. Странно, что у вас все еще происходит бесконечное перенаправление. Большинство браузеров сохраняют 301 редиректы в кеше. Я бы порекомендовал использовать Firebug для Firefox. Если вы используете FireBug, на вкладке Network в выпадающем меню есть опция отключения кеша браузера.

Florian Florian
29 апр. 2016 г. 11:44:07