Всякий раз, когда есть такой запрос на сервер
https://%{HTTP_HOST}/app/accounturi/services
Я хочу перенаправить его на
https://%{HTTP_HOST}/appLegacy/accounturi/services
здесь accounturi будет динамическим. Я пытаюсь это сделать в apache2.
Я попробовал следующее и остановился на RewriteRule.
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/(.*)services/?$ [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/appLegacy/
Эй, извините, что я испортил свой вопрос. Мне нужно переписать, а не перенаправить.
Таким образом, пользователь все равно должен видеть
https://%{HTTP_HOST}/app/accounturi/services
но запрос должен получить ответ от
https://%{HTTP_HOST}/appLegacy/accounturi/services
Пожалуйста, помогите с этим. Я прямо пишу это в конфигурации по умолчанию apache2 под
<VirtualHost *:443>
Я уже включил HTTPS для перенаправления ниже <VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
... Я предполагаю, что вы используете .htaccess? Если нет, то где в конфигурации сервера вы используете это правило?
Я прямо упоминаю об этом в конфигурации сайта по умолчанию в разделе <virtualhost:*443>.





RewriteCond %{REQUEST_URI} ^/(.*)services/?$ [NC] RewriteRule ^(.*)$ https://%{HTTP_HOST}/appLegacy/
Это приведет к 302 (временному) перенаправлению любого URL-адреса, оканчивающегося на services или services/, на https://<hostname>/appLegacy/ с потерей завершающей части <accounturi>/services.
Вы также не можете проверить /app в начале URL-пути? (Что заставляет меня думать, что ваш файл .htaccess находится внутри подкаталога /app? Но больше ничего не указывает на это.)
Если файл .htaccess находится внутри подкаталога /app, то правило должно быть таким:
RewriteRule ^([^/]+/services)/?$ /appLegacy/$1 [R=302,L]
Я предполагаю, что динамическая accounturi часть URL-пути состоит из одного сегмента пути (как в вашем примере).
Предыдущая директива RewriteCond не требуется. Обратная ссылка $1 содержит URL-путь, полученный из шаблона RewriteRule (это исключает любой необязательный завершающий слеш, который может присутствовать в запросе). Обратите внимание, что, поскольку файл .htaccess находится внутри подкаталога /app, он исключается из захваченного URL-пути.
Вам не нужно указывать абсолютный URL-адрес в качестве цели, поскольку вы, похоже, перенаправляете на тот же хост. Однако вы можете включить это, чтобы принудительно использовать HTTPS.
Однако, если файл .htaccess находится в корне документа, тогда директива должна быть такой и явно проверять наличие подкаталога /app:
RewriteRule ^app/([^/]+/services)/?$ /appLegacy/$1 [R=302,L]
ОБНОВЛЕНИЕ №1:
Я хочу переписать, а не перенаправить. и я прямо упоминаю об этом на странице конфигурации по умолчанию
Если это правило используется непосредственно внутри <VirtualHost: *:443> (согласно вашему обновлению), вам необходимо настроить правило следующим образом:
RewriteRule ^/app/([^/]+/services)/?$ /appLegacy/$1 [L]
Обратите внимание на префикс косой черты в шаблоне RewriteRule, поскольку в контексте виртуального хоста шаблон RewriteRule соответствует полному URL-пути относительно корня. И снятие флага R.
Это внутренне переписывает запрос, в отличие от перенаправления.
В стороне:
Я уже включил HTTPS для перенаправления ниже <VirtualHost *:80>
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Здесь вам не нужно использовать mod_rewrite. Достаточно простого mod_alias Redirect, и он будет более эффективным. И это должно быть перенаправление 301 (постоянное), а не 302 (временное), которое будет по умолчанию. Например:
Redirect 301 / https://example.com/
Однако вам потребуется жестко закодировать каноническое имя хоста в правиле.
ОБНОВЛЕНИЕ № 2:
иногда мы не передаем «accounturi» с URL-адресом, поэтому в этом случае он должен быть переписан на
https://%{HTTP_HOST}/appLegacy/servicesТаким образом,accounturiявляется необязательным.
Чтобы сделать accounturi (2-й сегмент пути) необязательным, измените правило следующим образом:
RewriteRule ^/app/(([^/]+/)?services)/?$ /appLegacy/$1 [L]
По сути, это делает часть [^/]+/ (2-й сегмент пути) необязательной, заключая ее в круглые скобки, за которыми следует ?. Необязателен только весь сегмент пути, а не только разделитель / (косая черта).
Кроме того: это также позволяет использовать необязательную косую черту в конце (перенесенную из начального «перенаправления» выше). Поскольку теперь это переписывание, необязательную косую черту в конце, вероятно, следует удалить, если она не требуется, поскольку она потенциально способствует дублированию контента (два разных URL-адреса, возвращающие один и тот же ресурс). Если вам нужно разрешить URL-адреса с завершающей косой чертой и без нее, необходимо добавить дополнительное правило (до перезаписи), которое перенаправляет с одного на другой (канонический URL-адрес).
пробовал ниже. Кажется, он работает нормально.
RewriteRule ^/app/((.*)+/?services)/?$ /appLegacy/$1 [L]
Это «работает» (вроде), но имеет пару больших недостатков:
Очень неэффективно. Использование подшаблона (.*)+ не имеет особого смысла (один или несколько из потенциально ничего). Подгруппа захвата (ненужная) на самом деле ничего не захватывает и делает регулярное выражение очень неэффективным, поскольку приводит к огромному количеству возвратов. Это регулярное выражение такое же, как ^/app/(.*/?services)/?$, но более эффективное. Но...
Слишком много совпадений. Если просто сделать / (перед services) необязательным, это может привести к слишком большому совпадению, поскольку оно совпадает с /app/<anything>services, включая URL-адреса, такие как /app/foo/bar/bazservices (обратите внимание на несколько сегментов пути и отсутствие косой черты перед services).
Эй, спасибо за это, я только что понял, что допустил ошибку в своем вопросе. Я хочу переписать, а не перенаправить. и я прямо упоминаю об этом на странице конфигурации по умолчанию.
@SanthoshKumar Я обновил свой ответ после вашего обновления.
Привет, я вижу, что это правильно перезаписывается с помощью appLegacy в журналах. Но иногда мы не передаем «accounturi» с URL-адресом, поэтому в этом случае его следует переписать на https://%{HTTP_HOST}/appLegacy/services. Таким образом, accounturi является необязательным.
Привет @MrWhite, я пытаюсь сделать этот «accounturi» необязательным и попробовал следующее. Кажется, он работает нормально. RewriteRule ^/app/((.*)+/?services)/?$ /appLegacy/$1 [L]
@SanthoshKumar Это «работает» (вроде как), однако регулярное выражение очень неэффективно и потенциально слишком много совпадает. Я обновил свой ответ.
Куда вы кладете файл
.htaccess? В корневом каталоге или внутри подкаталога/app?