Как получить доступ к каталогу index.php без завершающей косой черты И не получить 301 перенаправление

У меня есть эта структура: site.com/api/index.php. Когда я отправляю данные в site.com/api/, проблем нет, но я думаю, было бы лучше, если бы api работал без конечной косой черты, например: site.com/api. Это вызывает перенаправление 301 и, следовательно, теряет данные (поскольку данные не пересылаются). Я пробовал каждую переписывать, о которой я мог думать, и не мог избежать перенаправления. Это мое текущее правило повторной записи (хотя это может быть неактуально).

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/(.*)$ api/index.php [L]

Могу ли я заставить этот URL-адрес работать и поддерживать данные сообщения без использования косой черты?

Некоторые перезаписи, которые не работают: (все еще перенаправляются)

RewriteRule ^api$ api/index.php [L] 
RewriteRule ^api/*$ api/index.php [L]

Ответ 1

Сначала вам нужно отключить слэш каталога, но есть причина, по которой очень важно, чтобы у вас была конечная косая черта:

Mod_dir docs:

Отключение перенаправления трейлинг-косой черты может привести к раскрытию информации. Рассмотрим ситуацию, когда mod_autoindex активен (Options +Indexes) и DirectoryIndex установлен на допустимый ресурс (скажем, index.html), и для этого URL нет другого специального обработчика. В этом случае запрос с завершающей косой чертой отобразит файл index.html. Но запрос без косой черты перечислит содержимое каталога.

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

DirectorySlash Off

RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ /$1/

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^api/(.*)$ api/index.php [L]

Первое правило гарантирует, что конечная косая черта добавляется до конца, но только внутренне. В отличие от mod_dir, который внешне перенаправляет браузер, внутренняя переписка невидима для браузера. Следующее правило затем выполняет маршрутизацию api, и из-за первого правила гарантируется, что это будет завершающая косая черта.

Ответ 2

Если вы не хотите использовать решение, предоставленное Jon Lin (переконфигурирование всех ваших URL-адресов, указывающих на каталоги), вы можете использовать следующий код (обратите внимание на? в regexp - в основном он говорит, что конечная косая черта после "api" необязательно). Я не тестировал его, но он должен работать так:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/?(.*)$ api/index.php [L]