我在Nginx重写中遇到了一些麻烦。 我最近被博客移动到一个新的引擎,并且URL结构已经改变。 在我的旧博客引擎post位于一个forms为http://$host/yyyy/mm/title.html的URL上,但在新的引擎上,它们的格式为http://$host/yyyy/mm/title/ 。 服务器返回的实际文件位于/yyyy/mm/title/index.html 。
为了确保旧post中的链接仍然有效,我想在Nginx中进行重写,如下所示:
rewrite ^/(\d\d\d\d)/(\d\d)/(.+)\.html$ $scheme://$host/$1/$2/$3/ permanent;
不幸的是,这会捕获以.html结尾的任何内容,包括index.html ,因此访问forms为/(\d\d\d\d/)/(\d\d)/(.+)/的url会导致redirect循环(nginx内部尝试使用/$1/$2/$3/index.html ,redirect到/$1/$2/$3/ ,redirect到index.html等)。
如果可能,我宁愿不使用if语句。 有任何想法吗?
为了参考该网站是静态的,我的服务器configuration看起来像这样(这里没有什么奇特的):
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; } }
以下是预期redirect行为的一个简单示例:
http://blog.samwhited.com/2008/09/test.html – > http://blog.samwhited.com/2008/08/test/
如果可以隐藏index.html,那也是很好的。 没有我在网上find的工作。 所以这也可以工作:
http://blog.samwhited.com/2008/09/test/index.html – > http://blog.samwhited.com/2008/09/test/
你几乎需要使用一个if语句,但是如果你只有里面的rewrite指令,这样做是完全安全的。 你想检查$urivariables,因为这包括index模块所做的修改。
if ($uri !~ /index\.html$) { rewrite ^/test/(\d\d\d\d)/(\d\d)/(.+)\.html$ /$1/$2/$3/ permanent; }
要删除index.html部分,您需要发送一个redirect,但只有当客户端指定了index.html ,并且它不是由index模块添加的。 这意味着我们需要另一个if语句来检查这个。 我们在这里使用$request_urivariables,这是客户端实际发送的。
if ($request_uri ~ /index\.html($|\?)) { rewrite ^(.*)/index\.html$ $1/ permanent; }