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

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

我在 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;

不幸的是,这会捕获以 结尾的所有内容.htmlindex.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;
}

相关内容