Назад | Перейти на главную страницу

htaccess 301 перенаправление с ошибкой 500 с «?» в URL

Я пытаюсь перенаправить некоторые URL-адреса внутри.

Из:

https://example.com/?cat=123

Чтобы

https://example.com/?cat=456

В .htaccess файл, который я написал:

<IfModule mod_rewrite.c>
RewriteRule ^?cat=123$ https://example.com/?cat=456 [R=301,L]
</IfModule>

Но это вызывает ошибку сервера 500, и после некоторых проб и ошибок я обнаружил, что это вызвано ? персонаж в ?cat=123.

Если я удалю ?, 500 ошибка исчезнет, ​​хотя перенаправление не работает.

Кроме того, пока нет ? в старом URL перенаправление работает нормально.

Это отлично работает:

RewriteRule ^cat=123$ https://example.com/?cat=456 [R=301,L]

Это указывает ? в новом URL не вызывает проблемы.

Кажется, что в .htaccess файл не может распознать ? персонаж.

Кто-нибудь знает, как решить или избежать этой проблемы?

Проблема не в том ? в URL. Проблема в регулярном выражении, которое вы пытаетесь использовать ...

^?cat=123$

Это недопустимое регулярное выражение - причина внутренней ошибки сервера 500 (журнал ошибок сообщил бы, что регулярное выражение не может быть скомпилировано - или слова на этот счет). Это не относится к .htaccess - любой анализатор регулярных выражений выдал бы ту же ошибку.

В ? - это специальный метасимвол в регулярном выражении, который делает предыдущий элемент необязательным. Но ^ не поддается количественной оценке и, следовательно, не может быть «необязательным».

Однако есть что-то более фундаментальное неправильное в том, как вы пытаетесь это сделать. В RewriteRule шаблон соответствует только URL-пути, в частности исключает строку запроса (как обозначено ? в URL). Итак, пытаясь сопоставить строку запроса в RewriteRule директива никогда не будет работать.

Чтобы соответствовать строке запроса, т.е. все после первого ?, ты нуждаешься в RewriteCond директива, которая соответствует QUERY_STRING серверная переменная.

Например, для перенаправления с https://example.com/?cat=123 к https://example.com/?cat=456, вам нужно будет сделать что-то вроде следующего:

RewriteEngine On

RewriteCond %{QUERY_STRING} ^cat=123$
RewriteRule ^$ https://example.com/?cat=456 [R=302,L]

В ? не появляется как часть QUERY_STRING (или URL-путь) значение.

Если вам конкретно нужно сопоставить имя хоста, вам понадобится другой RewriteCond директива, которая соответствует HTTP_HOST серверная переменная. Если вы уже канонизировали схему + имя хоста и у вас есть только один домен, вы можете удалить схему + имя хоста из RewriteRule замена.

Измените 302 (временное) перенаправление на 301 (постоянное) только после того, как подтвердите, что это работает должным образом. 301-файлы постоянно кэшируются браузером, поэтому тестирование может быть проблематичным.

Я полагаю, у вас должно быть RewriteEngine директива уже в вашем коде. Нет необходимости в <IfModule mod_rewrite.c> оболочка, если вы не переносите эти директивы на несколько серверов, где mod_rewrite не может быть установлен, и это перенаправление по желанию?

пока нет ? в старом URL перенаправление работает нормально.

В этом случае нет строки запроса, только URL-путь, и все будет соответствовать RewriteRule шаблон.