Я переписываю конфигурацию Apache 2.4, которую я получил от старой разработки команда.
У меня есть ~200 строк похожей конфигурации, и я не могу понять, по какому принципу мне нужно изменить этот код, чтобы перенести его из .htaccess
в виртуальный хост.
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^(.*)$ /$1/ [R,L,NC]
Когда я просто перемещаю его на виртуальный хост, мой сайт падает в местах, которые я не понимаю.
Это зависит от того, где в контейнере <VirtualHost>
вы размещаете эти директивы.
Если вы используете контейнер <Directory>
(, т.е. каталог контекст)и отключение.htaccess
полностью переопределяет (иначе .htaccess
переопределит контейнер <Directory>
! ), тогда вы можете в значительной степени скопировать директивы, поскольку -это (, предполагая, что контейнер <Directory>
ссылается на тот же каталог, что и файл .htaccess
).
Однако, если вы помещаете эти директивы непосредственно внутрь контейнера <VirtualHost>
(вне контейнера <Directory>
), т.е. в контексте virtualhost , вам нужно внести некоторые изменения. Это связано с тем, что директивы обрабатываются раньше, до того, как запрос будет сопоставлен с файловой системой.
В опубликованных вами директивах потребуются только два изменения.:
В контексте виртуального хоста переменная сервера REQUEST_FILENAME
еще не преобразована в имя файла . ]. Это то же самое, что и REQUEST_URI
(, т.е. запрошенный URL). Таким образом, ваша проверка файловой системы всегда будет давать сбой, а условие всегда будет успешным! Вам либо нужно использовать просмотр вперед. например. %{LA-U:REQUEST_FILENAME}
или создайте абсолютное имя файла самостоятельно. например. %{DOCUMENT_ROOT}%{REQUEST_URI}
. Например,:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
В контексте виртуального хоста URL-путь, соответствующий шаблонуRewriteRule
, является корневым-относительным (, начинающимся с косой черты).. В то время как в .htaccess
это относится к каталогу, содержащему файл .htaccess
-, за вычетом префикса косой черты. Так,правило в том виде, в каком оно написано, приведет к двойной косой черте в начале URL-адреса-пути, вместо этого его следует переписать следующим образом:
RewriteRule ^/(.*)$ /$1/ [R,L]
(Флаг NC
здесь не требуется.)
Или (предпочтительнее)не используйте здесь обратную ссылку и используйте вместо нее (серверную переменную REQUEST_URI
, которая, естественно, будет работать и в .htaccess
). Например:
RewriteRule ^ %{REQUEST_URI}/ [R,L]
(В сторону:Вероятно, это тоже должен быть 301 постоянный редирект (т.е.R=301
). В нынешнем виде по умолчанию это будет временное перенаправление 302. Но переходите на 301 -, если это намерение -, только после того, как вы подтвердите, что он работает должным образом.)
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^/(.*)$ /$1/ [R,L]
В сторону:
Вышеупомянутое можно немедленно немного оптимизировать, переместив проверку файловой системы (, которая является относительно дорогой)в последнее условие и переместив условие , которое проверяет, что запрос еще не заканчивается косой чертой директивы RewriteRule
. Кроме того, подшаблоны регулярных выражений (.*)
в каждом из условий не требуются. Таким образом, приведенное выше можно было бы переписать более эффективно.:
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_URI} !^/application-module/
RewriteCond %{REQUEST_URI} !json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/ [NC]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule !/$ %{REQUEST_URI}/ [R,L]
Проверка файловой системы, возможно, может быть удалена полностью, если вместо этого вы исключите запросы, содержащие (что-то похожее на)расширение файла, но это может зависеть от вашей файловой структуры.
Условие , которое проверяет !json$
, выглядит так, как будто оно действительно должно проверять расширение файла .json
, т.е. !\.json$
. (Это связано с моим комментарием выше об исключении всех запросов, которые имеют "расширение файла".)
Первое условие , проверяющее, что строка запроса пуста, кажется немного странным, (поскольку на самом деле не имеет значения, есть ли строка запроса или нет при добавлении косой черты к URL-путь), но я предполагаю, что это должно быть особое требование?