68

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

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 以添加斜杠?(我认为我应该重写规则?)

4

10 回答 10

134

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

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

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

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

另一个常见的重写是:

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

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

于 2010-10-12T08:11:48.733 回答
30
rewrite ^([^.\?]*[^/])$ $1/ permanent;

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

例如

/myrest/do?d=12345

于 2013-05-19T23:01:30.267 回答
8

对于 nginx:

rewrite ^(.*[^/])$ $1/ permanent;
于 2010-09-25T01:26:39.463 回答
5

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

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

第二个,许多人更喜欢,因为如果不是 100% 必要,他们宁愿避免任何使用,是使用 try_files 在它不会命中文件时将请求发送到命名的位置块。例如

server {
   # ...
   location / {
      try_files $uri $uri/ @cms;
   }
   location @cms {
      rewrite [^/]$ $uri/ permanent;
      # CMS logic, e.g. rewrite ^ /index.php$request_uri;
   }
   # ...
}
于 2016-12-12T18:05:37.497 回答
3

为时已晚,但我想分享我的解决方案,我遇到了斜杠和 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 / {
    ....
    }
}
于 2016-02-01T07:30:31.157 回答
2
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也),以使其更具体。

于 2015-07-24T08:59:11.230 回答
1

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

if ($request_uri !~ "^/wp-admin")
{
rewrite ^([^.]*[^/])$ $1/ permanent;
rewrite ^([^.]*)$ /index.php;
}
于 2014-03-12T01:27:56.107 回答
0

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

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

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

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

于 2022-01-11T19:17:22.010 回答
0

如果 nginx 在代理后面使用 https,则此代码段会正确重定向$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;
    ...
}
于 2018-03-16T06:29:36.127 回答
-4

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

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

于 2009-03-14T12:48:01.087 回答