Я пытаюсь заставить работать правило перезаписи и обнаружил, что если URL-адрес начинается с вопросительного знака, Nginx не возвращает ошибку 404, как ожидалось. Вместо этого index.html, как определено в корневой директиве, обслуживается для всех URL-адресов, начинающихся с "?". (например. example.com/?page-does-not-exist
работает для домашней страницы, но не должно)
Это делает невозможным перенаправление с example.com/?format=feed&type=rss
-> example.com/rss.xml
работает. Это для блога, перенесенного с Joomla на Jekyll.
Проще говоря, посещение example.com/123 возвращает 404, и посещение example.com/?123 не. Последний возвращает домашнюю страницу сайта по URL-адресу example.com?/123. (Нет файла или папки "123", поэтому запросы на них всегда должны завершаться ошибкой.)
Все работает отлично с сайтом, включая перенаправление HTTPS, за исключением ожидаемых перенаправлений 404, которые не выполняются для URL-адресов, начинающихся со знака вопроса. Как это исправить?
Вот моя конфигурация:
server {
server_name example.com;
root /var/www/example.com;
index index.html;
listen 443;
ssl on;
...
rewrite "/?format=feed&type=rss" https://example.com/rss.xml permanent;
location ~* \.(?:ico|css|js|gif|jpeg|jpg|png|txt|svg|eot|woff|ttf)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
add_header Access-Control-Allow-Origin *;
valid_referers none blocked example.com;
if ($invalid_referer) {
return 403;
}
}
}
# HTTP --> HTTPS
server {
listen 80;
server_name www.example.com example.com;
return 301 https://example.com$request_uri;
}
Знак вопроса означает конец части пути в uri и начало строки запроса. Следовательно, почему nginx не возвращает 404 на основе части после вопросительного знака; запрошенный ресурс действительно существует, и ему просто передаются параметры строки запроса.
Что касается другой части вопроса, я считаю, что оператор rewrite nginx на самом деле не соответствует части строки запроса uri.
Однако вы должны иметь возможность делать что-то вроде:
if ($args ~ "format=feed&type=rss") {
rewrite ^ https://example.com/rss.xml? permanent;
}
NGinx
интерпретирует все, что следует за ?
как строка запроса, а не как путь.
Он вернет только 404 для несуществующего пути, но не для строки запроса.
например:
example.com/123
: если путь /123
существует, и если для этого пути есть индексный файл, тогда все в порядке, иначе он вернет 404
example.com/?123
: если в корневом каталоге есть индексный файл для example.com
тогда ладно. Он не проверяет, ?123
существует, поскольку он рассматривает это не как путь, а как строку запроса.