在每个 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 重写规则)的主要内容,如果未能解决你的问题,请参考以下文章