У меня есть HTTP-API, написанный на PHP, и я перенаправляю все вызовы на свой индекс. php, где (Slim-) маршрутизатор делает все остальное. Это работает.
Мое перенаправление в .htaccess
выглядит следующим образом:
Options +FollowSymLinks
Options -Indexes
RewriteEngine on
RewriteRule ^ index.php [QSA,L]
Существует только одна проблема: если одна конечная точка названа идентично с существующей папкой, происходят странные вещи. Это тот случай, когда я создаю конечную точку [PUT] /test
, в то время как есть также папка с именем test
, содержащая модульные тесты.
Вот что происходит:
- Если я вызов
[PUT] /test
с предпечатной проверкой Я вообще не получаю ответа на вызов OPTIONS, который приводит к сбою приложения. Это настоящий проблемный случай, так как мне нужен CORS. - Если я вызываю его без предварительной проверки и PUT, я получаю переадресацию 301 на одну и ту же конечную точку.
- Если я вызываю ее без предварительной проверки и POST, получаю 301 пересылка на ту же конечную точку, но с GET?!
Я думаю, мне нужно что-то изменить в .htaccess
, чтобы игнорировать существование папки, но что?
Как воспроизвести
Иметь сервер Apache и создать каталог следующим образом:
- / цель
- / цель / .htaccess
Options +FollowSymLinks
Options -Indexes
RewriteEngine on
RewriteRule ^ index.php [QSA,L]
<?php echo $_SERVER['REQUEST_URI'];
-
/ target / subfolder
/ testscript. html
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>test</title>
<style>
div {margin: 0.5em;}
.error { background: rgba(255, 0, 0, 0.3);}
.success { background: rgba(0, 255, 0, 0.3);}
</style>
</head>
<body>
<script>
const call = (url) => {
fetch(url, {
redirect: "manual",
method: "POST"
}).then(async response => {
const className = (response.redirected) ? 'success' : 'error';
const content = await response.text();
document.querySelector('body').innerHTML += `<div class='${className}'>${url}<hr /><b>[${response.status}]</b> ${content}</div>`;
});
};
call('target/endpoint');
call('target/subfolder');
</script>
</body>
</html>
Открыть http://localhost/
... testscript.html
в браузере и видите: вызов на target/subfolder
изменил свой метод. Также, когда вы смотрите на вкладку сети в консоли браузера, вы видите, что было 301 переадресация. Почему? И еще важнее: как я могу обойти это. Мое желаемое поведение - это перезапись без каких-либо изменений с точки зрения метода на index.php
, несмотря на существование папки с таким именем. Другими словами: то же самое, что происходит, когда я звоню target/endpoint
для target/subfolder
.
Я знаю о -d
(и -f
) естественно, но это можно использовать - насколько я знаю - чтобы управлять поведением в зависимости от того, существует ли файл или папка - поэтому я предположил бы, что без этих флагов существование каталога не должно играть никакой роли, но это, по-видимому, действительно.