我在 Nginx 重写方面遇到了一些麻烦。我最近将博客移至新引擎,URL 结构已发生改变。在我的旧博客引擎上,帖子位于具有 形式的 URL 中,http://$host/yyyy/mm/title.html
但在新引擎上,它们具有 形式http://$host/yyyy/mm/title/
。服务器返回的实际文件位于/yyyy/mm/title/index.html
。
为了确保旧帖子中的链接仍然有效,我想在 Nginx 中做一个重写,如下所示:
rewrite ^/(\d\d\d\d)/(\d\d)/(.+)\.html$ $scheme://$host/$1/$2/$3/ permanent;
不幸的是,这会捕获以 结尾的所有内容.html
,index.html
因此访问表单的 url/(\d\d\d\d/)/(\d\d)/(.+)/
会导致重定向循环(nginx 内部尝试使用/$1/$2/$3/index.html
,然后重定向到/$1/$2/$3/
,然后重定向回 index.html ,等等)。
如果可能的话,我宁愿不使用 if 语句。有什么想法吗?
作为参考,该网站是静态的,我的服务器配置看起来像这样(这里没什么特别的):
server {
listen [::]:80;
server_name blog.samwhited.com;
root /var/www/blog.samwhited.com;
charset utf-8;
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
error_page 404 /error/404.html;
error_page 403 /error/403.html;
location /error/ { internal; }
}
以下是预期重定向行为的简单示例:
http://blog.samwhited.com/2008/09/test.html->http://blog.samwhited.com/2008/08/test/
如果可以隐藏 index.html 就更好了。我在网上找到的所有方法都行不通。所以这个也可以:
http://blog.samwhited.com/2008/09/test/index.html->http://blog.samwhited.com/2008/09/test/
答案1
您几乎需要使用if
语句,但如果语句中只有指令,那么这样做是绝对安全的rewrite
。您需要检查$uri
变量,因为这包括模块所做的修改index
。
if ($uri !~ /index\.html$) {
rewrite ^/test/(\d\d\d\d)/(\d\d)/(.+)\.html$ /$1/$2/$3/ permanent;
}
要删除该index.html
部分,您需要发送重定向,但前提是客户指定了index.html
,但模块没有添加index
。这意味着我们需要另一个if
语句来检查这一点。我们$request_uri
在这里使用的变量是客户端实际发送的。
if ($request_uri ~ /index\.html($|\?)) {
rewrite ^(.*)/index\.html$ $1/ permanent;
}