【问题标题】:nginx : rewrite rule to remove /index.html from the $request_uringinx:重写规则以从 $request_uri 中删除 /index.html
【发布时间】:2011-08-06 06:04:57
【问题描述】:

当文件系统中存在特定文件时,我已经看到了一些重写$request_uri 并添加index.html 的方法,如下所示:

if (-f $request_filename/index.html) {
    rewrite (.*) $1/index.html break;
}

但我想知道是否可以实现相反的结果:

即当有人请求http://example.com/index.html时,他们会被重定向到http://example.com

因为 nginx 正则表达式是 perl 兼容的,所以我尝试了这样的方法:

if ( $request_uri ~* "index\.html$" ) {
    set $new_uri $request_uri ~* s/index\.html//
    rewrite $1 permanent;
}

但这主要是猜测,是否有任何描述 nginx 的 modrewrite 的好文档?

【问题讨论】:

    标签: nginx pcre


    【解决方案1】:

    我在顶级服务器子句中使用以下重写:

    rewrite ^(.*)/index\.html$ $1 permanent;
    

    单独使用它适用于大多数 URL,例如 http://example.com/bar/index.html,但它会破坏 http://example.com/index.html。为了解决这个问题,我有以下附加规则:

    location = /index.html {
      rewrite  ^ / permanent;
      try_files /index.html =404;
    }
    

    =404 部分在找不到文件时返回 404 错误。

    我不知道为什么单靠第一次重写是不够的。

    【讨论】:

    • ^(.*)/index\.html$ 对于(非常不可能的)你有 index/htmlindex2html 或其他东西的情况
    【解决方案2】:

    以下配置允许我将/index.html 重定向到//subdir/index.html/subdir/

    # Strip "index.html" (for canonicalization)
    if ( $request_uri ~ "/index.html" ) {
        rewrite ^(.*)/ $1/ permanent;
    }
    

    【讨论】:

      【解决方案3】:

      由于某种原因,这里提到的大多数解决方案都不起作用。那些有效的给了我在 url 中缺少 / 的错误。这个解决方案对我有用。

      粘贴您的位置指令。

      if ( $request_uri ~ "/index.html" ) {
        rewrite ^/(.*)/ /$1 permanent;
      }
      

      【讨论】:

        【解决方案4】:

        这个有效:

        # redirect dumb search engines
        location /index.html {
            if ($request_uri = /index.html) {
                rewrite ^ $scheme://$host? permanent;
            }
        }
        

        【讨论】:

          【解决方案5】:

          对于根/index.html,Nicolas 的回答导致了重定向循环,所以我不得不搜索其他答案。

          这个问题是在 nginx 论坛上提出的,那里的答案效果更好。 http://forum.nginx.org/read.php?2,217899,217915

          使用任一

          location = / {
            try_files /index.html =404;
          }
          
          location = /index.html {
            internal;
            error_page 404 =301 $scheme://domain.com/;
          }
          

          location = / {
            index index.html;
          }
          
          location = /index.html {
            internal;
            error_page 404 =301 $scheme://domain.com/;
          }
          

          【讨论】:

            【解决方案6】:

            这对我有用:

            rewrite ^(|/(.*))/index\.html$ /$2 permanent;
            

            它涵盖了根实例/index.html和较低的实例/bar/index.html

            正则表达式的第一部分基本上翻译为:[nothing]/[something] - 在第一种情况下 $2 是一个空字符串,所以你重定向到 /,在第二种情况下 $2 是[something] 所以你重定向到/[something]

            我实际上更喜欢报道index.htmlindex.htmindex.php

            rewrite ^(|/(.*))/index\.(html?|php)$ /$2 permanent;
            

            【讨论】:

            • 这使我陷入无限重定向循环,因为它尝试将 https 重定向到 http,然后我的负载均衡器将其重定向回 https
            • 这令人惊讶,我认为这只是一个双重重定向,nginx 剥离 index.html 并切换到 http,然后负载均衡器重定向回 https(但仍然没有index.html)。似乎您的 nginx 不知道它应该将“https”放在绝对 URL 中,也许您可​​以在 rewrite 语句中手动执行它,而不仅仅是“/$2”也许 https://$host/$2
            【解决方案7】:

            引用$scheme://domain.com/ 的解决方案假定域是硬编码的。这不是我的情况,所以我使用了:

            location / {
                ...
            
                rewrite index.html $scheme://$http_host/ redirect;
            
                ... }
            

            【讨论】:

            • 您好,这看起来不错,但您能否也解释一下(对于我们这些新手而言)为什么新解决方案效果更好?
            • 这是 nginx 配置中的一个特性。我凭经验发现(我可能错了)没有办法以相对方式引用根 / 页面。所以我被委托以绝对的方式引用它,为此我们必须给出它的完整方案和主机名(域名)。这个小技巧允许我们引用域名而无需对其进行硬编码。我发现它特别有用,因为我正在开发和使用该网站的单独 staging 和 Vagrant(虚拟机)版本。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多