Как мне перенаправлять и показывать содержимое с одинаковыми URL-адресами?

#apache #.htaccess #mod-rewrite #url-rewriting

#apache #.htaccess #мод-перезапись #переписывание URL-адресов

Вопрос:

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

если вызывается URL-адрес «/ abc /», он должен отображать содержимое, расположенное под «xyz.html «

я могу сделать это с

 RewriteRule abc$ xyz.html 
  

но «xyz.html » должно быть 301 перенаправление на «/abc», если оно вызывается.

Это моя простая проблема, я ищу решение с нескольких часов.

было бы легко, если бы это было похоже «test.html «и /проверить/. я могу сделать это следующим образом

 RewriteRule ^(. ).html$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*.html$ %{REQUEST_URI}.html [END]
  

Но в моем случае у меня есть куча URL-адресов без шаблона.

Все, что я пробовал, приводит к неправильной конфигурации сервера. Можете ли вы помочь мне с этим примером?

спасибо, kanuddel

Ответ №1:

Не могли бы вы попробовать следующее.

 RewriteEngine ON
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/abc/? [NC]
RewriteRule ^(.*) /xyz.html [L]

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/xyz.html/? [NC]
RewriteRule ^(.*) /abc/? [R=301,L]
  

Подробное объяснение:

Почему существует цикл перенаправления с обычным написанием правил: Вопрос из OP интересен и противоречив (вроде), почему, потому что, допустим, мы пишем 1-е правило для перенаправления (в серверной части) с abc URL-адреса на xyz.html него, будет работать нормально. Но затем, когда мы пишем наше 2-е правило, которое заключается в том, чтобы переписать URL-адрес с xyz.html на abc/ , который в точности противоположен первому правилу. Следовательно, это становится циклом, как можно скорее выполняются 1-е правила, оно переходит ко 2-му правилу и возвращает его к 1-му правилу, таким образом, БЕСКОНЕЧНЫЙ ЦИКЛ ПЕРЕНАПРАВЛЕНИЯ (до 50 циклов или около того).

Как предотвратить цикл перенаправления?

  • Во-первых, поскольку оба правила прямо противоположны друг другу, поэтому при обычном написании правил это станет циклом, теперь как мы можем предотвратить превращение его в цикл? Ответ использует: RewriteCond (объяснено на следующем шаге)

  • Я использовал ПЕРЕМЕННУЮ СРЕДЫ с именем ENV:REDIRECT_STATUS , значение которой будет иметь любой статус перенаправления. 2 вещи, которые нам нужно понять об этой переменной.

    1 — Без перенаправления запроса его значение по умолчанию равно NULL.

    2 — Всякий раз, когда мы выполняем успешное перенаправление, его значение становится 200 (НЕНУЛЕВЫМ), что мы можем использовать в нашей части условий.

Подробное объяснение правил htaccess:

  • Теперь перейдем к части с объяснением условия: в RewriteRule RewriteRule ^(.*) /xyz.html [L] я НЕ переписывал URL-адрес в браузере, почему из-за ПРАВИЛА БОЛЬШОГО ПАЛЬЦА мы всегда хотим показывать пользователям УДОБНЫЕ URL-адреса, поэтому переменная среды ENV:REDIRECT_STATUS здесь всегда будет равна НУЛЮ.

  • Теперь перейдем ко 2-му RewriteRule, RewriteRule ^(.*) /abc/? [R=301,L] где пользователь уже использует неудобный для пользователя URL-адрес, поэтому первым делом мне нужно переписать URL-адрес в браузере на удобный для пользователя URL-адрес, следовательно R=301 (здесь используется перенаправление с постоянным флагом). Как только перенаправление произойдет с помощью этого условия, 1-е условие начнет завершаться сбоем, почему, потому что это проверяет, имеет ли REDIRECT_STATUS переменная значение NULL, чего НЕТ после выполнения перенаправления из 2-го условия. Следовательно, это предотвращает цикл с помощью этого небольшого трюка 🙂

Ответ №2:

Спасибо за отличное объяснение!

Я попробовал это со вторым URL-адресом, где «/ xxx /» должен отображаться «zzz.html » Но это дало мне Неверное представление. Я попытался сократить его следующим образом:

 RewriteEngine ON
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/abc/? [NC]
RewriteRule ^(.*) /xyz.html [L]
RewriteCond %{REQUEST_URI} ^/xxx/? [NC]
RewriteRule ^(.*) /zzz.html [L]

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/xyz.html/? [NC]
RewriteRule ^(.*) /abc/? [R=301,L]
RewriteCond %{REQUEST_URI} ^/zzz.html/? [NC]
RewriteRule ^(.*) /xxx/? [R=301,L]