Как удалить косую черту из URL в nginx, только если каталог не существует?
Я использую сервер на nginx 1.4.1 с PHP-FastCGI. В настоящее время он настроен таким образом, что он удаляет косые черты из моих URL-адресов и выполняет редирект 301. Однако, когда я посещаю существующий каталог, я вынужден зацикливаться на перенаправлении. Мой текущий корень документа выглядит так:
- index.php (app)
- webgrind
- index.php
- static
- css
В настоящее время я не могу посетить example.com/webgrind или любой другой каталог. Мои журналы доступа многократно читаются как:
GET /webgrind/ HTTP/1.1" 301 178 "-"
GET /webgrind HTTP/1.1" 301 178 "-"
Это блок сервера в моем nginx.conf:
server {
listen 80;
server_name example.com;
location / {
try_files $uri $uri/ /index.php?$args;
root /var/www/example/public;
index index.php index.html index.htm;
}
rewrite ^/(.*)/$ /$1 permanent;
location = /favicon.ico {
access_log off;
log_not_found off;
}
location ~ \.php$ {
try_files $uri $uri/ /index.php?$args;
root /var/www/example/public;
index index.php index.html index.htm;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/example/public$fastcgi_script_name;
fastcgi_param APPLICATION_ENV testing;
fastcgi_param PATH /usr/bin:/bin:/usr/sbin:/sbin;
fastcgi_intercept_errors on;
include fastcgi_params;
}
}
Я знаю что rewrite ^/(.*)/$ /$1 permanent;
это оскорбительная линия Если я удаляю его и посещаю example.com/webgrind, выдается 301 для перенаправления на example.com/webgrind/, поскольку это каталог. Тем не менее, мое приложение теперь будет принимать как конечные, так и не конечные слеши (например, example.com/users/ и example.com/users), и это не то, что я хочу.
Оборачивание директивы if вокруг моего перезаписи следующим образом создает цикл перенаправления для моих каталогов (очевидно, если это зло, но в этом случае директива перезаписи считается безопасной):
if (!-d $request_filename) {
rewrite ^/(.*)/$ /$1 permanent;
}
(Я знаю, что посещение webgrind / index.php решит мою проблему, но я бы хотел избежать дорогостоящих и непрофессиональных циклов перенаправления, когда мои производственные каталоги запускаются.)
Так как же я могу условно удалить конечные косые черты только для несуществующих ресурсов (пути моего веб-приложения)?
ОБНОВЛЕНИЕ: мой (неизменный) конфиг fastcgi_params:
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
1 ответ
Ввод root
директива вне location
блок как прямое дитя server
блок исправил проблему.
server {
listen 80;
server_name example.com;
# This WORKS!
root /var/www/example/public;
location / {
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;
}
if (!-d $request_filename) {
rewrite ^/(.*)/$ /$1 permanent;
}
location = /favicon.ico {
access_log off;
log_not_found off;
}
location ~ \.php$ {
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/example/public$fastcgi_script_name;
fastcgi_param APPLICATION_ENV testing;
fastcgi_param PATH /usr/bin:/bin:/usr/sbin:/sbin;
fastcgi_intercept_errors on;
include fastcgi_params;
}
}
По-видимому, это ловушка, которую вики Nginx рекомендует избегать.