Я пытаюсь написать некоторые RewriteRules, чтобы, когда запрос содержит определенный параметр запроса, назовем его foo
, он полностью игнорировался (удалялся). Причина этого в том, что мне нужно использовать foo
внутри другого правила RewriteRule, чтобы я мог передавать информацию на мой фронт-контроллер. Если бы foo
уже существовало, приложение не работало бы должным образом. Я пробовал несколько решений, например это, но это не то, чего я хотел бы достичь. До сих пор я пробовал следующее:
<IfModule mod_rewrite.c>
RewriteEngine On
# Remove possible existing query parameter called 'foo'
RewriteCond %{QUERY_STRING} ^(.*)&?foo=[^&]+&?(.*)$ [NC]
RewriteRule ^(.*)$ /$1?%1%2 [R=301,L]
# Lead every page/API request to index.php
RewriteCond $1 !\.(svg|jpg|png|webp|ico|css|js|ttf|woff|woff2)$
RewriteRule ^(.*)$ index.php?foo=$1 [L,QSA]
</IfModule>
По сути, каждый запрос, который не заканчивается одним из перечисленных расширений файла, должен быть передан моему переднему контроллеру. Без строк 5 и 6 все работает нормально, если в исходном запросе нет параметра запроса foo
.
Есть ли способ просто удалить параметр foo
, не затрагивая другое правило RewriteRule (или просто переопределить его во второй части)? Заранее спасибо!
Редактировать
Просто поясню несколько вещей: в моем приложении фронт-контроллер — это PHP-скрипт, который принимает переписанный параметр GET foo
, который содержит исходный запрошенный URL-адрес. Однако, если пользователь добавляет foo
к запросу, я должен убедиться, что это не параметр foo
, который передается фронт-контроллеру, поскольку тогда приложение не будет работать должным образом.
Например: если клиент запрашивает https://example.com/something?foo=123&bar=456
, запрос должен быть перенаправлен на https://example.com/something?bar=456
(или вообще не перенаправлен), а параметр запроса foo
в строке 9, предназначенный только для моего фронт-контроллера, должен быть https://example.com/something
, а bar
не изменяться. . К сожалению, приведенный выше код этого не сделает. Вместо этого меня перенаправляют на https://example.com/index.php?bar=456
. Я думаю, что решение на самом деле довольно простое, но я не могу понять, как это сделать.
На самом деле речь идет о том, как «зарезервировать» определенный параметр запроса для внутреннего использования. Я уточню это в своем вопросе в ближайшее время.
Не могли бы вы попробовать следующее. убедитесь, что вы очистили кеш браузера, прежде чем тестировать URL-адреса. Учитывая, что здесь вам нужно, чтобы все после &
в строке запроса было передано в переписанном URL-адресе здесь. Добавлено 2 существующих правила из файла htaccess OP, а измененное место для правила https переместило его на самое первое место.
RewriteEngine ON
##From OP's comments adding these here, http --> https should come first.
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]
# Remove possible existing query parameter called 'foo'
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^(.*)&?foo=[^&]+&?(.*)$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}?%1%2 [NE,L]
# Lead every page/API request to index.php
RewriteCond $1 !\.(svg|jpg|png|webp|ico|css|js|ttf|woff|woff2)$
RewriteRule ^(.*)$ index.php?foo=$1 [L,QSA]
Мой браузер говорит Error: Request could not be executed
. Первоначально он был на немецком языке, надеюсь, этот перевод имеет смысл.
@Boostinger, мне жаль, что мой мобильный телефон сделал автокоррекцию, не могли бы вы проверить правила сейчас и сообщить мне тогда.
Теперь ошибка исчезла, но это не мешает мне использовать параметр запроса. Чтобы быть уверенным, я должен заменить свои строки 5 и 6? Кстати, спасибо за ваши усилия.
@Boostinger, круто. Итак, я вижу, что у вас уже есть правило для foo, так что вы заменяете эти правила ими, пожалуйста, подтвердите один раз
Оба "блока"? Я думаю, что это не передаст foo
моему контроллеру, если я заменю оба. Я прав? Итак, что я сделал, так это заменил только первое условие + правило (строки 5 и 6).
@Boostinger, не могли бы вы попробовать мои отредактированные правила один раз и, пожалуйста, дайте мне знать, как они идут, и да, попробуйте поместить эти правила на 5-ю и 6-ю строчки.
Контроллер по-прежнему получает foo
, переданный в моем запросе, а не переписанную версию в соответствии с моими строками 9 и 10.
@Boostinger, когда я проверяю URL-адрес http://localhost/something?foo=123&bar=456
, он переписывается на http://localhost/something?bar=456
в моей локальной сети, и я сохранил ваше второе правило также в своем файле htaccess. Не могли бы вы сообщить мне, есть ли у вас какие-либо другие правила в вашем файле htaccess, кроме этих 2.
Да, я удаляю завершающие косые черты и принудительно использую https, кроме упомянутых правил. RewriteCond %{HTTPS} off RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1 [R=301,L]
(извините за плохое форматирование)
@Boostinger, хорошо, продолжайте делать это правило https
в качестве самых первых правил, размещайте их над этими двумя правилами. Также нужно ли проверять ваше второе правило, например, в URL есть http://localhost:80/page/API?b;blablabla
? Если да, то мы также можем включить это условие в ваше текущее правило API, дайте мне знать об этом один раз.
Да, последнее обновление работает! Единственный случай, когда он все еще ведет себя по-другому, - это корень. Если я запрошу https://example.com/?foo=123&bar=456
, содержимое $_GET
в моем PHP-скрипте будет Array ( [foo] => foo=123 [bar] => 456 )
.
@Boostinger, здорово, что это сработало для большинства URL-адресов :), честно говоря, я не уверен насчет части php, так что вы хотите сказать, что ваша переменная $_GET
должна иметь здесь только значение [bar]
? Если да, то случайно наше 3-е правило влияет на это? Не могли бы вы также опубликовать пример рабочих URL-адресов (вместе с моим предыдущим вопросом в самом этом комментарии), пожалуйста, дайте мне знать.
Я просто добавил вывод PHP, чтобы вы могли видеть, какие значения сейчас содержат параметры. Это должно выглядеть так, чтобы работать как задумано: Array ( [foo] => [bar] => 456 )
- поэтому ожидается, что foo
будет пустой строкой, потому что это корень. Обратите внимание, что foo
получит значение something
вместо /something?foo=123&bar=456
, что уже отлично работает. В качестве ответа на ваш предыдущий вопрос: я думаю, что URL-адреса, как в вашем примере, в данный момент не нужны.
@Boostinger, рад, что мой ответ помог вам, а также, если новое условие не работает ИЛИ вы в порядке без нового условия в 3-м правиле, пожалуйста, дайте мне знать, тогда оно будет удалено из решения.
Я это проверю. Я думаю, что это уже работало до этого последнего изменения, как кажется. Прошу прощения, возможно, я что-то не так написал при проверке. Спасибо за помощь!
@Boostinger, о, ладно, тогда никаких проблем, я добрался до предыдущего (без дополнительного условия проверки статуса перенаправления в 3-м правиле), ура и счастливого обучения, продолжайте делиться на этом замечательном форуме.
@Boostinger, для строки правила RewriteCond %{QUERY_STRING} ^(.*)&?foo=[^&]+&?(.*)$
выражение .*
действительно жадно, если у вас есть только 2 раза &
в вашей строке, тогда мы могли бы сделать ее лучше, если вы подтвердите это, я добавлю ее позже утром, ура.
без проблем. Если есть лучшее/более чистое решение, просто добавляйте его всякий раз, когда у вас есть время. Теперь он работает для меня, так что я счастлив. Но мне все еще интересно, как это сделать правильно, конечно, и я проверю, если будет что-то новое.
Это действительно здорово, что вы поделились своими усилиями и файлом htaccess в своем вопросе, так держать. Не могли бы вы также указать, с какого URL-адреса (только образцы) на какой URL-адрес (бэкэнд) вы хотите обслуживать, для большей ясности вашего вопроса, спасибо.