URL-адрес переписать, чтобы изменить определенную часть URL-адреса на основе ключевого слова

Всякий раз, когда есть такой запрос на сервер

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? В корневом каталоге или внутри подкаталога /app?

MrWhite 17.04.2023 15:59

... Я предполагаю, что вы используете .htaccess? Если нет, то где в конфигурации сервера вы используете это правило?

MrWhite 17.04.2023 17:19

Я прямо упоминаю об этом в конфигурации сайта по умолчанию в разделе <virtualhost:*443>.

Santhosh Kumar 18.04.2023 14:06
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
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]

Это «работает» (вроде), но имеет пару больших недостатков:

  1. Очень неэффективно. Использование подшаблона (.*)+ не имеет особого смысла (один или несколько из потенциально ничего). Подгруппа захвата (ненужная) на самом деле ничего не захватывает и делает регулярное выражение очень неэффективным, поскольку приводит к огромному количеству возвратов. Это регулярное выражение такое же, как ^/app/(.*/?services)/?$, но более эффективное. Но...

  2. Слишком много совпадений. Если просто сделать / (перед services) необязательным, это может привести к слишком большому совпадению, поскольку оно совпадает с /app/<anything>services, включая URL-адреса, такие как /app/foo/bar/bazservices (обратите внимание на несколько сегментов пути и отсутствие косой черты перед services).

Эй, спасибо за это, я только что понял, что допустил ошибку в своем вопросе. Я хочу переписать, а не перенаправить. и я прямо упоминаю об этом на странице конфигурации по умолчанию.

Santhosh Kumar 18.04.2023 13:11

@SanthoshKumar Я обновил свой ответ после вашего обновления.

MrWhite 18.04.2023 17:14

Привет, я вижу, что это правильно перезаписывается с помощью appLegacy в журналах. Но иногда мы не передаем «accounturi» с URL-адресом, поэтому в этом случае его следует переписать на https://%{HTTP_HOST}/appLegacy/services. Таким образом, accounturi является необязательным.

Santhosh Kumar 19.04.2023 06:49

Привет @MrWhite, я пытаюсь сделать этот «accounturi» необязательным и попробовал следующее. Кажется, он работает нормально. RewriteRule ^/app/((.*)+/?services)/?$ /appLegacy/$1 [L]

Santhosh Kumar 21.04.2023 06:14

@SanthoshKumar Это «работает» (вроде как), однако регулярное выражение очень неэффективно и потенциально слишком много совпадает. Я обновил свой ответ.

MrWhite 21.04.2023 13:18

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