Почему перенаправление в.htaccess не работает?

У меня есть веб-сайт Wordpress. Я хочу перенаправить URL-адреса.php на те, у которых нет суффикса.php..htaccess выглядит следующим образом:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On


RewriteRule ^(.*)\.php$ "$1" [R=301,L,NC]


RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule. /index.php [L]
</IfModule>

# END WordPress

Но когда я захожу https://www.example.com/somepage.php, страница не отображается. В браузере отображается следующая ошибка:

The page isn’t redirecting properly

    An error occurred during a connection to www.example.com.
    
        This problem can sometimes be caused by disabling or refusing to accept cookies.

И URL-адрес в адресной строке становитсяhttps://www.example.com/index.

Если я изменю правило перезаписи на:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On


RewriteRule ^(.*)\.html$ "$1" [R=301,L,NC]


RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule. /index.php [L]
</IfModule>

# END WordPress

и посещу https://www.example.com/somepage.html, оно будет успешно перенаправлено наhttps://www.example.com/somepageи веб-страница будет отображаться нормально. Почему?

2
задан 1 December 2021 в 14:45
1 ответ

Потому что, поскольку редирект безусловный,в конечном итоге вы снова перенаправляете после URL-адрес был переписан в индекс .php(фронт-контроллер WordPress).

Когда вы запрашиваете /somepage.php:

  1. Вы перенаправляетесь на /somepage(по первому правилу). Ответ перенаправления отправляется обратно клиенту.
  2. По второму запросу /somepageвнутренне переписывается на /index.phpпоследним правилом. Затем механизм перезаписи запускается заново (в контексте каталога )...
  3. /index.phpперенаправляется на /index(по первому правилу). Ответ перенаправления отправляется обратно клиенту.
  4. По третьему запросу /indexвнутренне переписывается на /index.phpпутем последнего переписывания. Затем механизм переписывания запускается заново...
  5. Goto 3 (застрял в бесконечном цикле перенаправления).

В контексте каталога (например, .htaccess)механизм переписывания не просто делает один проход через скрипт. Он зацикливается до тех пор, пока URL-адрес не пройдет без изменений. (Если вы не используете флаг ENDна Apache 2.4 или не происходит внешнее перенаправление 3xx.)

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

Чтобы решить эту проблему, необходимо избегать перенаправления переписанного запроса. Вы можете сделать это либо:

  • , используя флаг END(Apache 2.4+) при последнем перезаписи, вместо L, чтобы предотвратить дальнейшие циклы движка перезаписи. Хотя вы должны избегать изменения стоковых директив WordPress (см. Ниже), поэтому это может быть не предпочтительным вариантом. Это также не работает на Apache 2.2.

  • Или проверьте наличие расширения .phpс серверной переменной THE_REQUEST(который содержит начальную строку заголовков HTTP-запроса и не изменяется при переписывании запроса). Например:

    # Удалить расширение ".php" только для "прямых" (не переписанных) запросов
    RewriteCond %{THE_REQUEST} [A-Z]{3,7}\s/[^?] +\.php(?:\?| \s|$) [НК]
    ПереписатьПравило (.+)\.php$ /$1 [R=301,L,NC]
    
  • Или проверьте переменную среды REDIRECT_STATUS, которая пуста при первоначальном запросе и имеет значение 200 (как в состоянии HTTP 200 OK) при первой успешной перезаписи (это проще, чем довольно сложное регулярное выражение выше). Например:

    # Удалить расширение ".php" только на "прямых" (не переписанных) запросах
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    ПереписатьПравило (.+)\.php$ /$1 [R=301,L,NC]
    

Тем не менее, вы не должны редактировать код внутри раздела # BEGIN WordPress, так как wordPress сам пытается поддерживать это и может перезаписать этот код позже. Это правило должно идти перед маркером комментариев # BEGIN WordPress.Вам не нужно повторять директиву RewriteEngine On, которая появляется позже в файле (в разделе WordPress).

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

Однако само по себе это не позволяет вам получить доступ к файлам .phpбез расширения .php. Поскольку URL-адрес без расширения необходимо будет внутренне переписать обратно в файл .php.

2
ответ дан 1 December 2021 в 15:37

Теги

Похожие вопросы