Nginx 重写除 index 之外的所有 html 文件

Sam*_*ted 4 rewrite nginx

我在 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;
Run Code Online (Sandbox Code Playgroud)

不幸的是,这种捕捞任何有目的.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; }
}
Run Code Online (Sandbox Code Playgroud)

以下是预期重定向行为的快速示例:

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/

mgo*_*ven 5

您几乎需要使用if语句,但如果您只rewrite在其中包含指令,那么这样做是完全安全的。您想要检查$uri变量,因为这包括index模块所做的修改。

if ($uri !~ /index\.html$) {
    rewrite ^/test/(\d\d\d\d)/(\d\d)/(.+)\.html$ /$1/$2/$3/ permanent;
}
Run Code Online (Sandbox Code Playgroud)

要删除index.html您需要发送重定向的部分,但前提是客户端指定了index.html,并且它不是由index模块添加的。这意味着我们需要另一个if语句来检查这一点。我们在$request_uri这里使用客户端实际发送的变量。

if ($request_uri ~ /index\.html($|\?)) {
    rewrite ^(.*)/index\.html$ $1/ permanent;
}
Run Code Online (Sandbox Code Playgroud)