【问题标题】:Add slash to the end of every url (need rewrite rule for nginx)在每个 url 的末尾添加斜杠(需要为 nginx 重写规则)
【发布时间】:2010-10-13 08:24:18
【问题描述】:

我尝试在每个网址末尾添加一个“/”:

example.com/art

应该

example.com/art/

我使用 nginx 作为网络服务器。

我需要重写规则。

为了更好地理解,请查看:

http://3much.schnickschnack.info/art/projekte

如果您按下大图片下方的小缩略图,它会重新加载并显示此网址:

http://3much.schnickschnack.info/art/projekte/#0

如果我现在在所有 url 上都有一个斜线(最后),它可以在不重新加载网站的情况下工作。

现在我在 nginx-http.conf 中有这个设置:

server {
  listen *:80;
  server_name 3much.schnickschnack.info;
  access_log /data/plone/deamon/var/log/main-plone-access.log;
  rewrite ^/(.*)$ /VirtualHostBase/http/3much.schnickschnack.info:80/2much/VirtualHostRoot/$1 last;
  location / {
    proxy_pass http://cache;
  }
}

如何配置 nginx 以添加斜杠? (我认为我应该重写规则?)

【问题讨论】:

  • 嗯...为什么要在所有 URL 的末尾添加 /?
  • 我需要它来做一个 js 画廊。如果没有“/”,它会重新加载网站...
  • 我需要nginx的重写规则......
  • 所以问题是“如何配置 nginx 以添加斜杠?”或者是“我如何配置 nginx 以在没有斜杠的情况下工作?”
  • 问题应该:如何配置nginx添加斜线?

标签: regex nginx rewrite


【解决方案1】:

这条规则也解决了查询字符串的情况:

location ~ ^/([^.]*[^/])$ {
  if ($query_string) {
    return 301 $scheme://$host/$1/?$query_string;
  }
  return 301 $scheme://$host/$1/;
}

正则表达式取自@marc 的回答: rewrite ^([^.\?]*[^/])$ $1/ permanent;

在正则表达式中添加了额外的斜线^/ 以提高可读性

【讨论】:

    【解决方案2】:

    如果 nginx 使用 https 进行代理,这个 sn-p 会正确重定向 $scheme

    map $http_x_forwarded_proto $upstream_scheme {
        "https" "https";
        default "http";
    }
    
    server {
        ...
        location / {
            rewrite ^([^.\?]*[^/])$ $upstream_scheme://$http_host$1/ permanent;
        }
        ...
    }
    

    并在上游代理上传递X-Forwarded-Proto 标头,如:

    location / {
        proxy_set_header X-Forwarded-Proto $scheme;
        ...
    }
    

    【讨论】:

      【解决方案3】:

      奇怪这是谷歌的第一个结果,但没有一个令人满意的答案。我知道有两种很好的方法可以做到这一点。首先是直接检查请求是否会命中文件,如果不是,则仅应用重写条件。例如

      server {
         # ...
         if (!-f $request_filename) {
           rewrite [^/]$ $uri/ permanent;
         }
         location / {
            # CMS logic, e.g. try_files $uri $uri /index.php$request_uri;
         }
         # ...
      }
      

      第二个,很多人更喜欢,因为他们宁愿避免任何非 100% 必要的 if 的使用,是使用 try_files 将请求发送到指定的位置块,当它获胜时不要打文件。例如

      server {
         # ...
         location / {
            try_files $uri $uri/ @cms;
         }
         location @cms {
            rewrite [^/]$ $uri/ permanent;
            # CMS logic, e.g. rewrite ^ /index.php$request_uri;
         }
         # ...
      }
      

      【讨论】:

        【解决方案4】:

        为时已晚,但我想分享我的解决方案,我遇到了斜杠和 nginx 的问题。

        #case : 
        # 1. abc.com/xyz  => abc.com/xyz/
        # 2. abc.com/xyz/ => abc.com/xyz/
        # 3. abc.com/xyz?123&how=towork => abc.com/xyz/?123&how=towork
        # 4. abc.com/xyz/?123&ho=towork => abc.com/xyz/?123&how=towork
        

        这是我的解决方案

        server { 
            ....
            # check if request isn't static file
            if ($request_filename !~* .(gif|html|jpe?g|png|json|ico|js|css|flv|swf|pdf|xml)$ ) {
               rewrite (^[^?]+[^/?])([^/]*)$ $1/$2 permanent;
            }
            ....
            location / {
            ....
            }
        }
        

        【讨论】:

        • 我真的很喜欢你的解决方案。它帮助了我:)。它还可以使用更通用的正则表达式进行文件匹配:if ($request_filename !~* .[a-zA-Z0-9]+$ ) 这应该匹配任何文件。
        【解决方案5】:
        server {
            # ... omissis ...
        
            # put this before your locations
            rewrite ^(/.*[^/])$ $1/ permanent;
        
            # ... omissis ...
        }
        

        如果您希望阻止某种请求(比如GET 之外的请求)执行此操作(通常是关于POST 请求,因为rewrite 将任何请求方法转换为GET,这可能会中断您网站的一些动态功能),添加if 子句:

        server {
            # ... omissis ...
        
            # put this before your locations
            if ($request_method = "GET" ) {
                rewrite ^(/.*[^/])$ $1/ permanent;
            }
        
            # ... omissis ...
        }
        

        您也可以将rewrite 放在location 块中(if 也可以),以使其更具体。

        【讨论】:

          【解决方案6】:

          在 Wordpress 中使用来自 anthonysomerset 的重写,我尝试了由于 reirection 循环而访问 /wp-admin 仪表板的问题。但我使用上述条件解决了这个问题:

          if ($request_uri !~ "^/wp-admin")
          {
          rewrite ^([^.]*[^/])$ $1/ permanent;
          rewrite ^([^.]*)$ /index.php;
          }
          

          【讨论】:

            【解决方案7】:
            rewrite ^([^.\?]*[^/])$ $1/ permanent;
            

            为了避免休息 url 的查询字符串得到 / 标记。

            例如

            /myrest/do?d=12345

            【讨论】:

            • 你怎么能得到结果``` /myrest/do/?d=12345 ``
            • @PatrickLeeScott 添加“?”我认为用正则表达式排除就足够了
            • @PatrickLeeScott 我已经添加了一个答案
            【解决方案8】:

            我认为你更可能想要这样的东西:

            rewrite ^([^.]*[^/])$ $1/ permanent;
            

            正则表达式转换为: “重写所有不带任何'的URI。'在不以 '/' 结尾的 URI + '/'" 或者简单地说: "如果 URI 没有句点且不以斜杠结尾,则在末尾添加斜杠"

            只重写不带点的 URI 的原因是,任何带有文件扩展名的文件都不会被重写。例如你的图片、css、javascript等,如果使用一些自己重写的php框架,可以防止可能的重定向循环

            另一个常见的重写是:

            rewrite ^([^.]*)$ /index.php;
            

            这非常简单地将所有没有句点的 URI 重写为您的 index.php(或您将从中执行控制器的任何文件)。

            【讨论】:

            • 这是互联网上唯一没有在所有内容中添加斜杠的帖子。感谢发帖。
            • 这个工作更可靠,特别是对于有漂亮链接重写的 php 框架
            • 我有静态 html 文件,因此:domain.com/about 获取文件 domain.com/about.html 但仍显示不带“.html”的 URL。我希望在点击文件后添加一个斜杠,但如果我添加一个斜杠,现在会得到一个 404。所以我想删除尾部斜杠(如果存在)并且有或没有尾部斜杠获取“-html”文件但在之后显示“/”。这不起作用:rewrite ^/([a-zA-Z0-9]+)$ /$1.html; rewrite ^([^.]*[^/])$ $1/ permanent; 也可以多次单击菜单中的“关于”,我得到这个 domain.com/about/about/about 等..
            • 查询字符串呢?
            • @EtienneMartin 看起来它会将domain.com/page?thing=abc 重写为domain.com/page?thing=abc/。还是nginx单独检测和处理查询字符串?
            【解决方案9】:

            对于 nginx:

            rewrite ^(.*[^/])$ $1/ permanent;
            

            【讨论】:

            • 这将为所有内容添加一个斜线 - 所以你最终会得到 index.php -> index.php/ 和 page?a=b -> page?a=b/ OP 肯定想要的是 page?a=b -> page/?a=b
            【解决方案10】:

            试试这个:^(.*)$ http://domain.com/$1/ [L,R=301]

            这会将不带“/”的所有内容 ($1)(状态代码 301)重定向到“$1/”

            【讨论】:

            • Gomez:您绝对应该将非斜杠 URL 301(重定向)到斜杠 URL,或者搜索引擎等会将 example.com/blah 和 example.com/blah/ 完全视为两个单独的页面
            • 我刚刚测试了这个。 ^(.*)$ 无论如何都会重定向所有内容。我不得不改用 ^(.*)[^/] ,所以它只会在没有结尾斜杠的情况下重定向。
            • 这个答案似乎为 Apache 提供语法,但最初的问题是针对 nginx 的。
            猜你喜欢
            • 2013-11-08
            • 2010-11-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多