NGINX删除.html扩展名

时间:2016-07-06 15:55:23

标签: html nginx

所以,我找到了删除页面上.html扩展名的答案,该代码可以正常使用:

server {
    listen 80;
    server_name _;
    root /var/www/html/;
    index index.html;

    if (!-f "${request_filename}index.html") {
        rewrite ^/(.*)/$ /$1 permanent;
    }

    if ($request_uri ~* "/index.html") {
        rewrite (?i)^(.*)index\.html$ $1 permanent;
    }   

    if ($request_uri ~* ".html") {
        rewrite (?i)^(.*)/(.*)\.html $1/$2 permanent;
    }

    location / {
        try_files $uri.html $uri $uri/ /index.html;
    }
}

但如果我打开mypage.com,它会将我重定向到mypage.com/index
通过将index.html声明为索引来解决这个问题吗?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:29)

"圣杯"删除" .html"的解决方案在NGINX中:

更新的答案:这个问题激起了我的好奇心,我继续寻找另一个更深入的搜索圣杯" Nginx中.html重定向的解决方案。这是我找到的答案的链接,因为我自己没有提出答案:https://stackoverflow.com/a/32966347/4175718

但是,我将举例说明它是如何运作的。这是代码:

location / {
    if ($request_uri ~ ^/(.*)\.html$) {
        return 302 /$1;
    }
    try_files $uri $uri.html $uri/ =404;
}

这里发生的事情是对if指令非常巧妙的使用。 Nginx在传入请求的$request_uri部分运行正则表达式。正则表达式检查URI是否具有.html扩展名,然后将URI的无扩展部分存储在内置变量$1中。

来自docs,因为我需要一段时间来确定$1的来源:

  

正则表达式可以包含可供以后在$ 1 .. $ 9变量中重复使用的捕获。

正则表达式都检查是否存在不需要的.html请求,并有效地清理URI,使其不包含扩展名。然后,使用简单的return语句,请求被重定向到现在存储在$1中的已清理的URI。

正如原作者cnst所解释的那样,最好的部分是

  

由于$ request_uri在每个请求中始终是常量,并且不受其他重写的影响,因此它实际上不会形成任何无限循环。

与对任何 .html请求进行操作的重写(包括对/index.html的不可见内部重定向)不同,此解决方案仅对可见的外部URI进行操作用户。

" try_files"办?

您仍然需要try_files指令,否则Nginx将不知道如何处理新近清理的无扩展URI。上面显示的try_files指令将首先尝试新的URL,然后使用" .html"扩展名,然后将其作为目录名称。

Nginx文档还解释了默认try_files指令的工作原理。默认的try_files指令的排序方式与上面的示例不同,因此下面的解释并不完美排列:

  

Nginx将首先将.html附加到URI的末尾并尝试提供它。如果找到合适的.html文件,它将返回该文件并维护无扩展名URI 。如果找不到合适的.html文件,它将尝试不带任何扩展名的URI,然后将URI作为目录,最后返回404错误。

更新:正则表达式做什么?

上面的答案涉及正则表达式的使用,但对于那些仍然很好奇的人来说,这里有一个更具体的解释。使用以下正则表达式(正则表达式):

^/(.*)\.html$

这打破了:

^:表示行的开头。

/:匹配字符" /"从字面上。正斜杠不需要在Nginx中进行转义。

(.*):捕获组:无限次匹配任何角色

\.:匹配角色"。"从字面上。必须使用反斜杠进行转义。

html:匹配字符串" html"字面上。

$:表示行尾。

捕获组(.*)包含非" .html"网址的一部分。稍后可以使用变量$1来引用它。然后将Nginx配置为重新尝试请求(return 302 /$1;),并在try_files指令内部重新附加" .html"扩展名,以便找到该文件。

更新:保留查询字符串

要保留传递到.html页面的查询字符串和参数,可以将return语句更改为:

return 302 /$1?$args;

这应该允许/index.html?test之类的请求重定向到/index?test,而不仅仅是/index

请注意,这被认为是`if`指令的安全用法。

来自Nginx页面如果是邪恶:

  

如果在位置环境中,可以在内部完成的唯一100%安全的事情是:

     

返回...;

     

重写...最后;

另请注意,您可以换掉' 302'重定向到' 301'。

301重定向是永久性的,并由网络浏览器和搜索引擎进行缓存。如果您的目标是从已经被搜索引擎编入索引的网页中永久删除.html扩展名,则您需要使用301重定向。但是,如果您在实际网站上进行测试,最佳做法是从302开始,只有在您确信配置正常运行时才转移到301

答案 1 :(得分:1)

这也经常出现在我身上,由于工作中的配置,位置块最多也是最好的而且/& .php块被锁定。这意味着大多数解决方案对我不起作用。

所以这是我从上面接受的答案中简化的一个。

rewrite ^/(.*)\.html /$1/ permanent;

适用于CMS,其中底层框架正在生成页面