如果没有后面的斜杠,Nginx 会导致301重定向

我使用 NAT 在虚拟机中运行 nginx,当我从主机访问它时出现了重定向问题。

果然有效

  • 工作。
  • 工作。

没有预期的效果

  • 重定向到 http://localhost/test/。这是我想要的

我已经尽力了

根据我在谷歌上搜索的内容,我尝试了 server_name_in_redirect off;rewrite ^([^.]*[^/])$ $1/ permanent;,但都没有成功。

我的默认设置 conf:

server {
listen       80;
server_name  localhost;
# server_name_in_redirect off;
    

location / {
root   /usr/share/nginx/html;
index  index.html index.htm index.php;
}


location ~ \.php$ {
# rewrite ^([^.]*[^/])$ $1/ permanent;
root           /usr/share/nginx/html;
try_files      $uri =404;
#fastcgi_pass   127.0.0.1:9000;
fastcgi_pass   unix:/tmp/php5-fpm.sock;
fastcgi_index  index.php;
include        fastcgi_params;
}




error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   /usr/share/nginx/html;
}


}
64035 次浏览

Try changing

server_name  localhost;
# server_name_in_redirect off;

to

server_name  localhost:8080;
server_name_in_redirect on;

try :

server {
listen       80;
server_name  localhost;
location / {
root   /usr/share/nginx/html;
index  index.html index.htm index.php;
if (-d $request_filename) {
rewrite [^/]$ $scheme://$http_host$uri/ permanent;
}
}
}

I posted a possible solution to this problem on serverfault; reproduced here for convenience:

If I understand the question correctly, you want to automatically serve, without using a 301 redirect, http://example.com/foo/index.html when the request is for http://example.com/foo with no trailing slash?

Basic solution that works for me

If so I've found this try_files configuration to work:

try_files $uri $uri/index.html $uri/ =404;
  • The first $uri matches the uri exactly
  • The second $uri/index.html matches a directory containing the index.html where the last element of the path matches the directory name, with no trailing slash
  • The third $uri/ matches the directory
  • The fourth =404 returns the 404 error page if none of the preceding patterns match.

Taken from Serverfault answer

My updated version

If you add in the server block:

index index.html index.htm;

And modify try_files to look like this:

try_files $uri $uri/ =404;

It should work too.

A somewhat simpler solution, that worked for me, is to disable absolute redirects with absolute_redirect off; as in the following example:

server {
listen 80;
server_name  localhost;
absolute_redirect off;


location /foo/ {
proxy_pass http://bar/;
}

If I run curl on on http://localhost:8080/foo, I can see that the Location header in the redirect HTTP response is given as /foo/ and not http://localhost/foo/.

$ curl -I http://localhost:8080/foo
HTTP/1.1 301 Moved Permanently
Server: nginx/1.13.8
Date: Tue, 03 Apr 2018 20:13:28 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: /foo/

From that, I assume any web-browser would do the right thing with the relative location. Tested on Chrome and it works fine.