Перепишите движок в .htaccess, чтобы перехватывать файлы, не заканчивающиеся на html

StackOverflow https://stackoverflow.com/questions/604012

Вопрос

Я бы хотел использовать mod rewrite для преобразования адресов веб-страниц, таких как /каталог Для /directory/index.html, в стандартной ситуации размещения LAMP.То, что у меня есть, работает для адресов, которые заканчиваются косой чертой.Я не могу найти способ справиться адреса, которые не заканчиваются косой чертой.

Кажется, что это должно сработать, так это:

rewriterule ^(.*)/$ $1/index.html [L] /* addresses ending in / */
rewriterule ^(.*(?!html))$ $1/index.html [L] /* where the problem is */

Но вторая строка вызывает ошибку сервера 500.Если я добавлю одну букву x ко второй строке:

rewriterule ^(.*)/$ $1/index.html [L]
rewriterule ^(.*x(?!html))$ $1/index.html [L]

Это начинает работать, но только для имен каталогов, которые заканчиваются на x.Я пробовал заменять крестик множеством разных вещей.Все, что сложнее реальных символов (например, [^x] или .+) выдает ошибку сервера 500.

И, чтобы удовлетворить мое собственное любопытство, кто-нибудь знает, почему добавление одной реальной буквы делает разницу между ошибкой сервера и идеально функционирующим правилом?

[Принятый ответ] Благодаря Gumbo я смог приблизить решение, используя rewritecond:

rewritecond %{REQUEST_URI} !\.[^/]+$
rewriterule (.+) $1/index.html [L]

Это работает, но фильтрует не только .html - он может блокировать другие страницы.К сожалению,

rewritecond %{REQUEST_URI} !\.html$

приводит к ошибке сервера:

Запрос превысил лимит в 10 внутренних перенаправлений из-за вероятной ошибки конфигурации.Используйте "LimitInternalRecursion", чтобы при необходимости увеличить лимит.

Я все еще хотел бы знать, почему:

rewriterule ^(.*(?!html))$ $1/index.html [L]

приводит к циклу.Предполагается, что первая половина должна проверить, так ли это не делает заканчивается на .html.Начиная со второго тайма добавляет .html, это похоже на функциональный эквивалент:

while(substr($address,-4)!='html') $address.='html'

Очевидно, я что-то упускаю.

Это было полезно?

Решение

Используйте RewriteCond директива для проверки того, не заканчивается ли URL-адрес на .html:

RewriteCond %{REQUEST_URI} !\.html$
RewriteRule ^(.*[^/])?/?$ $1/index.html [L]

Редактировать   Вы используете прогнозируемое утверждение ((?!…)).Но после этого ничего не будет .* (только a $).Так что попробуйте вместо этого заглянуть за утверждение:

RewriteRule ^.*$(?<!html) $0/index.html [L]

Но обратите внимание, что вам, вероятно, понадобится Apache 2.2, чтобы использовать эти утверждения.

Другие советы

Ну, чтобы на самом деле заставить это работать, вы могли бы просто использовать отрицательный взгляд назад вместо предвидения:

RewriteRule ^(.*)(?<!html)$ $1/index.html [L]

Я не уверен сразу, почему добавление буквы "x" заставляет это работать, я отредактирую, если разберусь.

Для чего добавлять x заставляет это работать:Если замена будет соответствовать регулярному выражению, RewriteRule будет применен снова.В качестве примера, это приводит к ошибке:

RewriteRule ^(.*)$ $1.rb

потому что это заменило бы script с script.rb.Это соответствует регулярному выражению, поэтому оно заменяет script.rb с script.rb.rb, снова и снова...

На это намекается журнал ошибок:

Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary.

В вашем примере вы добавляете index.html в конце.Когда есть возможность x в конце регулярного выражения оно не будет соответствовать вашей замене, которая заканчивается на l.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top