我正在用PHP-FastCGI在nginx 1.4.1上运行一个服务器。 目前我有它的设置,以便从我的url中删除尾部的斜杠,并发出301redirect。 但是,当我访问一个存在的目录,我被迫进入redirect循环。 我目前的文档根目录是这样的:
- 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,则会发出一个301redirect到example.com/webgrind/,因为它是一个目录。 但是,我的应用程序现在将接受尾随和非尾随斜杠(即example.com/users/和example.com/users),这不是我想要的。
在我的重写周围包装“if”指令,如下所示,仍然为我的目录创build一个redirect循环( 如果是邪恶的 ,显然,在这种情况下,重写指令被认为是安全的):
if (!-d $request_filename) { rewrite ^/(.*)/$ /$1 permanent; }
(我知道访问webgrind / index.php会解决我的问题,但我想避免成本高昂和不专业的redirect循环,当我的生产目录被推动生活。)
那么,我怎样才能有条件地去除尾随的斜线(仅适用于不存在的资源)(我的Web应用程序path)?
更新 :我的(未改变)fastcgi_paramsconfiguration:
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;
将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 wiki建议避免的一个陷阱 。