Правило перезаписи с QUERY_STRING не работает

На сервере Apache мне нужно переписать mydomain.com/something/?p=value в mydomain.com/something/?page= значение

Я пробовал:

RewriteEngine On
RewriteCond %{QUERY_STRING} p=(.*)
RewriteRule ^(.*)/p=$ $1?page=%{QUERY_STRING} [L,QSA]

но не просыпаюсь, может мне помочь?

2
задан 22 October 2020 в 15:33
1 ответ
RewriteCond %{QUERY_STRING} p=(.*)
RewriteRule ^(.*)/p=$ $1?page=%{QUERY_STRING} [L,QSA]

Здесь много "ошибок":

  • Шаблон RewriteRule , т.е. ^(.*)/p=$, никогда не будет совпадать, потому что p= не встречается как часть URL-пути (это часть строки запроса). Шаблон RewriteRule соответствует только URL-пути, что, в частности, исключает строку запроса. Таким образом, приведенное выше ничего не сделает для указанного примера URL.

  • Вы используете серверную переменную QUERY_STRING вместо требуемого параметра URL value в строке замены. Но QUERY_STRING, очевидно, представляет собой всю «строку запроса», поэтому в конечном итоге будет построена искаженная строка запроса в форме: page=p=.

  • Использование флага QSA приводит к тому, что исходная строка запроса в запросе объединяется со строкой запроса, которую вы используете в строке замены. Таким образом, это приведет к добавлению &p=, а это не то, что вам нужно. Вы хотите заменить существующую строку запроса.

  • Правило перезаписи ^(.*)/p=$ $1?page= — вы исключаете конечный слэш из группы захвата в шаблоне RewriteRule , поэтому это эффективно удалит конечный слэш из переписанного URL-адреса. . Это отличается от вашего примера.

  • Похоже, вам требуется внутреннее изменение (без внешнего перенаправления), и вы «только» меняете имя одного параметра URL. Это то, что вы обычно разрешаете в своем приложении, а не переписываете URL-адрес в Apache. (?)

Вместо этого попробуйте следующее:

RewriteEngine On

# Internally "rewrite" the request
RewriteCond %{QUERY_STRING} ^p=([^&]*)$
RewriteRule (.*/)$ $1?page=%1 [L]

Это соответствует любому URL-пути, заканчивающемуся косой чертой (как в вашем примере). Обратная ссылка %1 относится к захваченной группе в последнем сопоставленном CondPattern, т.е. значение параметра p URL. Предполагается, что p= — единственный параметр URL в запросе.


ОБНОВЛЕНИЕ: кажется, что это не работает... если я вызову localhost/list/?p=2, я просто получу localhost/list/?p=2

Да, видимый URL-адрес не меняется, поскольку это внутренняя «перезапись» (как вы, похоже, просите в своем вопросе). URL-адрес внутренне переписан в list/?page=2. (Существует также тот факт, что list/?page=2 не является строго действительной конечной точкой — она требует дальнейшей перезаписи, возможно, с помощью mod_dir для формирования действительного запроса. Например, list/index.php?page=2?)

Если вы хотите, чтобы URL-адрес заметно изменился, возможно, вам все-таки требуется внешняя «переадресация»? Для этого вам нужно включить префикс косой черты в строку RewriteRule substitution и добавить флаг R (redirect). Например:

# Externally "redirect" the request
RewriteCond %{QUERY_STRING} ^p=([^&]*)$
RewriteRule (.*/)$ /$1?page=%1 [R=302,L]

если я изменю правило, чтобы получить localhost/list/?p=2&?p=2, как показано ниже:

RewriteEngine On
Условия перезаписи %{QUERY_STRING} ^p=([^&]*)$
Правило перезаписи (.*/)$ $1&?страница=%1 [Л]

я получаю сообщение «Запрошенный URL-адрес /list/& не найден на этом сервере». в виде '?' вырезать перезапись

Если вы запросите localhost/list/?p=2&?p=2 (но зачем?), то указанная выше директива вообще ничего не сделает, так как условие не соответствует.

Зачем вы добавили & в строку RewriteRule подстановки? (Это не имеет смысла?) Это действительно привело бы к URL-пути формы /list/&, если бы правило было обработано. Но, как уже говорилось, он не будет обработан для указанного вами URL-адреса?

2
ответ дан 22 October 2020 в 14:13

Теги

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