Apache htaccess несколько условий перезаписи для нескольких правил
Я взял на себя веб-сайт и заметил, что предыдущий разработчик имел несколько .htaccess
переписать правила, это короткий пример:
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)/(.*)$ landing.php?page=$1&id=$2&mid=$3
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)$ landing.php?page=$1&id=$2
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing$ landing.php?page=$1
Условие перезаписи всегда одинаково для всех правил. Есть ли способ объединить правила перезаписи, чтобы условия были записаны только один раз?
Я посмотрел на пропускающий флаг, но он не имеет обратной ссылки. Насколько я вижу, мне не нужны обратные ссылки с этими условиями, однако, является ли пропустить лучший подход? Или есть лучшая практика, как этого добиться? (Кто-то предложил мне использовать флаг QSA, однако после исследования я не думаю, что это имеет какое-либо отношение к тому, чего я хочу достичь.)
2 ответа
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$ RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$ RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$ RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
Этот грязный блок условий вводится автоматически cPanel перед каждым RewriteRule
директива при автоматическом обновлении сертификата безопасности SSL (Let's Encrypt?). Эти условия обеспечивают доступность файла проверки (необходимого для обновления сертификата SSL).
К сожалению, я не смог понять, почему cPanel делает это таким образом - это может быть кошмаром обслуживания, и я столкнулся с директивами, которые были нарушены этими условиями (по общему признанию, директивы были не идеальны с самого начала). (Я пытался спрашивать на форумах cPanel, но у меня никогда не было хорошего ответа.)
... есть ли способ объединить правила перезаписи, чтобы условия были записаны только один раз?
Да. Вы можете переместить эти условия в свой блок в начале .htaccess
файл и обратить их значение, так что вместо того, чтобы вызвать RewriteRule
когда запрос не соответствует шаблону (используя отрицательное регулярное выражение). Вы можете предотвратить дальнейшие перезаписи, когда запрос соответствует шаблону. Например:
# BEGIN cPanel SSL CERT RENEWAL
RewriteCond %{REQUEST_URI} ^/[0-9]+\..+\.cpaneldcv$ [OR]
RewriteCond %{REQUEST_URI} ^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$ [OR]
RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$ [OR]
RewriteCond %{REQUEST_URI} ^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^ - [L]
# END cPanel SSL CERT RENEWAL
Обратите внимание на удаление !
(отрицание) префикс на CondPattern и дополнительный OR
флаг на первых трех условиях. RewriteRule
затем предотвращает дальнейшую обработку директив mod_rewrite, если запрос совпадает.
(На Apache 2.4.8+ эти директивы могут быть полностью перенесены в конфигурацию сервера. С помощью RewriteOptions InheritDownBefore
.)
Затем следуют только RewriteRule
директивы у вас были раньше (хотя я добавил L
флаг):
RewriteRule ^(.*)/landing/(.*)/(.*)$ landing.php?page=$1&id=$2&mid=$3 [L]
RewriteRule ^(.*)/landing/(.*)$ landing.php?page=$1&id=$2 [L]
RewriteRule ^(.*)/landing$ landing.php?page=$1 [L]
Вы, вероятно, должны быть в том числе L
флаги на тех оставшихся переписывает.
Вы также можете объединить эти 3 переписки в одну директиву, если хотите, но это будет зависеть от того, будет ли ваше приложение обрабатывать пустые параметры URL.
(Кто-то предложил мне использовать флаг QSA, однако после исследования я не думаю, что это имеет какое-либо отношение к тому, чего я хочу достичь.)
Да, это не имеет ничего общего с этой конкретной проблемой. QSA
Флаг (Query String Append) позволит вам объединить любую строку запроса, которая присутствует в запросе, со строкой запроса, которую вы пишете в RewriteRule
замена.
Проблема:
Например, у вас есть такие условия и правила:
RewriteCond %{REQUEST_URI} ^(...COND_1...)$
RewriteCond %{REQUEST_URI} ^(...COND_2...)$
RewriteRule ^(...RULE_1_FROM...)$ (...RULE_1_TO...)
RewriteCond %{REQUEST_URI} ^(...COND_1...)$
RewriteCond %{REQUEST_URI} ^(...COND_2...)$
RewriteRule ^(...RULE_2_FROM...)$ (...RULE_2_TO...)
RewriteRule ^(...RULE_3_FROM...)$ (...RULE_3_TO...)
Условия №1 и №2 одинаковы, и вам необходимо применить правила №1 и №2 в этих условиях. Правило №3 не зависит от условий №1 и №2 и должно быть отделено от этих условий.
Решение:
Если вы не хотите повторять условие №1 и условие №2 каждый раз для каждого правила, вам следует внести 2 изменения:
Изменение 1. Создайте противоположные условия из №1 и №2:
RewriteCond %{REQUEST_URI} !^(...COND_1...)$ [OR]
RewriteCond %{REQUEST_URI} !^(...COND_2...)$
(Я добавил!
песок[OR]
здесь).
Изменение 2. У вас есть 2 правила, связанных с этими условиями, поэтому добавьте эту строку после всех условий:RewriteRule ^ - [S=2]
. Цифра в квадратных скобках — это ряд правил , которые необходимо применять в данных условиях. Если у вас есть 3 строки правил, вы должны написатьRewriteRule ^ - [S=3]
и так далее.
Вот полный код:
RewriteCond %{REQUEST_URI} !^(...COND_1...)$ [OR]
RewriteCond %{REQUEST_URI} !^(...COND_2...)$
RewriteRule ^ - [S=2]
RewriteRule ^(...RULE_1_FROM...)$ (...RULE_1_TO...)
RewriteRule ^(...RULE_2_FROM...)$ (...RULE_2_TO...)
RewriteRule ^(...RULE_3_FROM...)$ (...RULE_3_TO...)