кажется, что при доступе к site.com/api/v1/ не выполняется api_v1.php. Вместо этого он продолжит и выполнит index.php
Да, потому что первое правило переписывает запрос на api_v1.php
и это в конечном итоге переписывается на index.php
по второму правилу (потому что php
нет в списке исключенных расширений в первом условие, второе условие также выполняется успешно, поэтому третье условие не обрабатывается (см. ниже) во время второго прохода механизма перезаписи. В каталог контекст (т. .htaccess
) л
флаг не останавливает всю обработку, он просто останавливает текущий проход через механизм перезаписи. Механизм перезаписи работает до тех пор, пока URL-адрес не пройдет без изменений.
Вы можете решить эту проблему на Apache 2.4, используя КОНЕЦ
флаг вместо л
, по первому правилу остановить всю обработку переписывающим движком.
Например:
RewriteRule ^api/v1/api_v1.php [NC,END]
(я удалил конец (.*)$
на регулярном выражении, поскольку здесь это не обязательно и делает регулярное выражение незначительно менее эффективным.)
Однако тот факт, что запрос на существующую .php
файл переписан вашими более поздними правилами, действительно демонстрирует, что ваши вторые и третьи правила, похоже, не работают должным образом...
№ 2. Перепишите в index.php, за исключением существующих файлов design/document/favicon/robots
RewriteCond %{REQUEST_URI} !.(css|js|png|jpg|jpeg|bmp|gif|ttf|eot|svg|woff|woff2|ico|webp|pdf)$
RewriteCond %{REQUEST_URI} !^(robots\.txt|favicon\.ico)$ [ИЛИ]
RewriteCond %{REQUEST_FILENAME} !-f
Правило перезаписи ^(.*)$ index.php [L]
№3. Перепишите все остальное
Правило перезаписи ^(.*)$ index.php [L]
Если вы запрашиваете что-то.php
затем первый условие успешно (потому что .php
является нет включены в список). Второе условие также выполнено (это не robots.txt
или же favicon.ico
). Поскольку второе условие явно объединяется с третьим условием, третье условие не обрабатывается.Все условия соблюдены и запрос переписан на index.php
(несмотря на погоду что-то.php
есть или нет).
Если, с другой стороны, вы просите ресурс.css
затем первый условие терпит неудачу (потому что он имеет .css
расширение). Поскольку это условие неявно объединяется по И, дальнейшие условия не обрабатываются и правило не срабатывает. Затем третье правило безоговорочно переписывает ресурс.css
к index.php
, независимо от того, существует он или нет!
Таким образом, это не проверяет, что запрошенный ресурс (css
, jpg
и т. д.) «существует», как следует из предыдущего комментария. Третье условие (которое проверяет, что запрос не отображается в файл) обрабатывается только в том случае, если предыдущее условие ИЛИ не выполняется И первое условие успешно. Другими словами, третье условие обрабатывается только тогда, когда вы запрашиваете /роботы.txt
- что, я уверен, не входит в ваши намерения.
Другими словами, правила № 2 и № 3 (несмотря на их кажущуюся сложность), похоже, в значительной степени переписываются. все к index.php
.
Комплексное решение
На основании ваших дополнительных комментариев:
Для подмножества типов файлов обслуживайте ресурс, если он существует. Если ресурс не существует, отправьте запрос на index.php
.
Для других типов файлов отправьте запрос на index.php
, независимо от того, существует этот ресурс или нет.
Несколько запросов (т. /роботы.txt
и /favicon.ico
) не следует отправлять index.php
.
Вместо этого попробуйте следующее:
# Предотвратить перенаправление 301 с косой чертой, когда папка существует и к ней не добавлена косая черта
# Это не проблема безопасности, так как используется PHP-маршрутизатор и все пути перенаправляются
Слэш-каталог выключен
# Поскольку установлено "DirectorySlash Off", убедитесь, что списки каталогов mod_auotindex отключены
Параметры - Индексы
RewriteEngine включен
№1. Переписать URL API
RewriteRule ^api/v1/api_v1.php [NC,END]
№ 2. Известные URL/файлы обслуживаются напрямую
RewriteRule ^(index\.php|robots\.txt|favicon\.ico)$ - [КОНЕЦ]
№3.Определенные типы файлов (ресурсы) обслуживаются напрямую, если они существуют
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule \.(css|js|png|jpe?g|bmp|gif|ttf|eot|svg|woff|woff2|ico|webp|pdf)$ - [КОНЕЦ]
№ 4. Перепишите все остальное
RewriteRule ^ index.php [КОНЕЦ]
Правила заканчиваются раньше для всего, что нужно обслуживать напрямую, поэтому нам нужно только переписать index.php
один раз в последнем правиле.
Обратите внимание, что я включил index.php
в правиле №2. Это оптимизация, хотя она и не является строго необходимой при использовании КОНЕЦ
флаг (в отличие от л
) по последнему правилу.
При желании вы можете выбрать перенаправление любого непосредственный просьбы к index.php
вернуться к корню (для канонизации URL для поисковых систем). Это на всякий случай /index.php
раскрывается (или угадывается) конечному пользователю.
Например, добавьте следующее после первого правила для API:
#1.5 Перенаправление прямых запросов к "/index.php" обратно в "/" (корневой)
Условия перезаписи %{ENV:REDIRECT_STATUS} ^$
Правило перезаписи ^index\.php$ / [R=301,L]
условие который проверяет против REDIRECT_STATUS
переменная среды необходима для предотвращения цикла перенаправления — чтобы избежать перенаправления переписанного URL-адреса. (Хотя, опять же, это не является строго обязательным при использовании КОНЕЦ
флаг на последнем/переписывающем правиле.)