在每个 url 的末尾添加斜杠(需要为 nginx 重写规则)

Posted

技术标签:

【中文标题】在每个 url 的末尾添加斜杠(需要为 nginx 重写规则)【英文标题】:Add slash to the end of every url (need rewrite rule for 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添加斜线? 【参考方案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 的。

以上是关于在每个 url 的末尾添加斜杠(需要为 nginx 重写规则)的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 URL 的末尾需要一个斜杠?

自动添加的 URL 末尾的 AFNetworking 斜杠

URL末尾处的斜杠“/”

URL重写在末尾添加斜杠会破坏我的css链接

tengine 末尾反斜线问题

斜杠(“/”)添加到我的返回 URL