【问题标题】:nginx static index redirectnginx 静态索引重定向
【发布时间】:2013-03-07 13:29:55
【问题描述】:

这看起来很荒谬,但我在一个多小时的搜索中没有找到有效的答案。

我有一个运行 nginx 的静态网站(恰好在 Varnish 后面)。索引文件称为index.html。我想将实际访问 URL mydomain.com/index.html 的任何人重定向回 mydomain.com

这是我的网站 nginx 配置:

server {
  listen  8080;
  server_name  www.mydomain.com;
  port_in_redirect  off;

  location / {
    root   /usr/share/nginx/www.mydomain.com/public;
    index index.html;
  }

  rewrite /index.html http://www.mydomain.com/ permanent;
}

http://www.mydomain.com/index.html 按预期响应301,位置为http://www.mydomain.com/,但不幸的是http://www.mydomain.com/ 也提供301 返回自身,因此我们得到一个重定向循环。

如果 index.html 确实在请求中,我如何告诉 nginx 只提供 301 服务?

【问题讨论】:

    标签: redirect nginx http-status-code-301


    【解决方案1】:

    添加一个新的位置块来处理您的主页,并使用 try_files 指令(而不是“index index.html;”)直接查找 index.html 文件。请注意,try_files 要求您至少输入 2 个选项。所以我把同一个文件放了两次。

    location = / {
      root   /usr/share/nginx/www.mydomain.com/public;
      try_files /index.html /index.html;
    }
    

    根据我的实验看起来不错:

    curl -iL http://www.mydomain.com/index.html
    HTTP/1.1 301 Moved Permanently
    Server: nginx
    Date: Sat, 16 Mar 2013 09:07:27 GMT
    Content-Type: text/html
    Content-Length: 178
    Connection: keep-alive
    Location: http://www.mydomain.com/
    
    HTTP/1.1 200 OK
    Server: nginx
    Date: Sat, 16 Mar 2013 09:07:27 GMT
    Content-Type: text/html
    Content-Length: 4
    Last-Modified: Sat, 16 Mar 2013 08:05:47 GMT
    Connection: keep-alive
    Accept-Ranges: bytes
    

    [更新] 重定向循环的根本原因是 'index' 指令,它触发 nginx 再次进行另一轮位置匹配。这就是位置块之外的重写规则再次执行的方式,从而导致循环。所以'index'指令就像一个“rewrite...last;”指示。你不希望这样。

    诀窍是不要再次触发另一个位置匹配。 try_files 可以有效地做到这一点。这就是我在原始答案中选择它的原因。但是,如果您愿意,另一个简单的解决方法是替换

      index index.html;
    

    通过

      rewrite ^/$ /index.html break;
    

    在您原来的“位置 /”块内。这个'重写......打破;'指令将使 nginx 保持在同一位置块内,有效地停止循环。但是,这种方法的副作用是您失去了 'index' 指令提供的功能。

    [更新 2]

    实际上,index 指令在 rewrite 指令之后执行。所以以下也有效。请注意,我刚刚添加了 rewrite...break;线。如果请求uri是“/”,nginx首先从rewrite规则中找到现有文件/index.html。所以这个请求永远不会触发 index 指令。因此,两个指令可以一起工作。

      location / {
        root   /usr/share/nginx/www.mydomain.com/public;
        index index.html;
        rewrite ^/$ /index.html break;
      }
    

    【讨论】:

    • 谢谢,这行得通。我真的不明白为什么会停止重定向循环,但确实如此。 try_files 可能有点神奇。您能解释一下为什么将try_files /index.html /index.html; 行放入existing 位置块不起作用吗? (我试过了)。干杯。
    • @Ade 我今晚稍后会解释。
    • @Ade 添加更多解释。不知道你是怎么做的你的第二次测试。请注意,您必须删除“索引”指令才能使其正常工作。
    • @ChuanMa 非常感谢您的解释 - 我对 nginx 比较陌生,现在开始更好地理解它。谢谢!
    • @Ade np。我再次更新了答案。你问了一个很好的问题。很高兴看到它对您有用!
    【解决方案2】:

    看起来你真的不希望index.php 出现在地址栏中,对吗?

    如果你在 nginx 配置中添加一个重写指令,你会得到一个重定向循环,正如你所经历的那样。如果您对 javascript 解决方案持开放态度,则可以将其放在 index.html 中的任何位置以静默地重写地址栏:

    <script>
        history.pushState(null, '', '/');
    </script>
    

    For more information

    请记住,虽然大多数现代浏览器都支持 history API,但并非所有浏览器都支持(即大多数版本的 IE)。

    【讨论】:

    • 谢谢;是的,我知道几种应用程序级别的重定向方法,但希望在服务器级别进行配置,因为它可以在多个应用程序中重用。
    猜你喜欢
    • 2015-12-14
    • 2020-11-05
    • 1970-01-01
    • 2018-10-30
    • 2011-06-14
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多