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

Posted

技术标签:

【中文标题】如果没有斜杠,Nginx 会导致 301 重定向【英文标题】:Nginx causes 301 redirect if there's no trailing slash 【发布时间】:2013-03-11 10:18:11 【问题描述】:

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

按预期工作

http://localhost:8080/test/index.htm:有效。 http://localhost:8080/test/:有效。

没有按预期工作

http://localhost:8080/test:重定向到http://localhost/test/。这不是我想要的。 (注意它会去掉端口号)

我尝试过的

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

我的 default.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;
    


【问题讨论】:

【参考方案1】:

尝试改变

server_name  localhost;
# server_name_in_redirect off;

server_name  localhost:8080;
server_name_in_redirect on;

【讨论】:

【参考方案2】:

试试:

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;
        
    

【讨论】:

【参考方案3】:

我在serverfault 上发布了解决此问题的可能方法;为方便起见,在此转载:

如果我正确理解了这个问题,当请求是针对 http://example.com/foo 而没有尾部斜杠时,您想自动提供 http://example.com/foo/index.html,而不使用 301 重定向?

适合我的基本解决方案

如果是这样,我发现这个 try_files 配置可以工作:

try_files $uri $uri/index.html $uri/ =404;
第一个 $uri 与 uri 完全匹配 第二个$uri/index.html 匹配包含index.html 的目录,其中路径的最后一个元素匹配目录 名称,不带斜杠 第三个$uri/ 匹配目录 如果前面的模式都不匹配,第四个=404 返回 404 错误页面。

取自Serverfault answer

我的更新版本

如果您在server 块中添加:

index index.html index.htm;

并将try_files 修改为如下所示:

try_files $uri $uri/ =404;

应该也可以。

【讨论】:

@maiconsanson - 它似乎适用于我的子文件夹。欢迎进一步解释。 对不起,我的意思是,它可以工作,但没有找到 index.html 中的图像。顺便说一句,我用 Dokku 来解决这个问题:if (-d $request_filename) rewrite [^/]$ $scheme://$http_host$uri/ permanent; buildpack-nginx index.html 中的相对路径可能以某种方式损坏。检查页面试图检索的 url,并与图像实际所在的 url 进行比较,看看问题是否变得更清楚。 网址没问题(1.png 等)。一切都在根应用程序中(index.html 和图像)。 为 try_files 点赞++ $uri $uri/index.html $uri/ =404;逻辑!成功了谢谢【参考方案4】:

一个对我有用的更简单的解决方案是使用absolute_redirect off; 禁用绝对重定向,如下例所示:

server 
    listen 80;
    server_name  localhost;
    absolute_redirect off;

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

如果我在 http://localhost:8080/foo 上运行 curl,我可以看到重定向 HTTP 响应中的 Location 标头是 /foo/ 而不是 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/

据此,我认为任何网络浏览器都会对相对位置做正确的事情。在 Chrome 上测试,它工作正常。

【讨论】:

这仍然返回 301 这是对问题的解释和实际解决方案:serverfault.com/a/812461 据我了解,这个问题实际上并不是在抱怨 301 本身。 301 很好,并且可以预期,问题是重定向应该指向相同的服务器名称保持端口 8080。 这对我来说很好用。对于额外的偏执狂,您可以将 absolute_redirect off 范围限定为 location 块,如果您只是需要它用于特定位置 您只需要在 server 块中使用 try_files $uri $uri/index.html $uri/ =404;。但请确保使用curl 对其进行测试。浏览器缓存东西。因此,如果您点击一次重定向,它可以继续这样做。

以上是关于如果没有斜杠,Nginx 会导致 301 重定向的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有斜杠的情况下访问目录的 index.php 并且不获得 301 重定向

带有 nginx 的 Gatsby - 重定向被破坏 - 尾随 /(斜杠)

为啥在 URL 中缺少尾部斜杠 (/) 时会发生重定向?

深度硬核文:Nginx的301重定向处理过程分析

如何禁用 301 重定向,在 Apache 中将斜杠添加到目录名称

当 url 没有斜杠时,AWS s3 强制 302 重定向 - 需要 301s