NGINX删除.html扩展名

Sky*_*n42 10 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Arn*_*non 35

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

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

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

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

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

文档中,我花了一段时间才弄清楚它来自何处$1:

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

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

正如原作者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$
Run Code Online (Sandbox Code Playgroud)

这打破了:

^:表示行的开头.

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

(.*):捕获组:无限次匹配任何字符

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

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

$:表示行尾.

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

更新:保留查询字符串

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

return 302 /$1?$args;
Run Code Online (Sandbox Code Playgroud)

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


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

来自Nginx页面如果是邪恶:

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

回来......;

重写...最后;


另请注意,您可以将'302'重定向换成'301'.

一个301重定向是永久性的,并且通过网络浏览器和搜索引擎的缓存.如果您的目标是.html从搜索引擎已编入索引的网页中永久删除扩展程序,则需要使用301重定向.但是,如果您在实际站点上进行测试,最好从a开始,302只有301在绝对确信配置正常工作时才转到a .

  • 这是关于堆栈溢出的答案应该如何的一个很好的例子 (4认同)
  • @WillB由于301重定向是由浏览器缓存的,我喜欢使用302,除非我100%确定我永远不想撤消重定向.从我所看到的情况来看,谷歌似乎并不太关心,如果有一天你决定要回到你的网址中的.html扩展名,那么它就会变得容易多了. (3认同)
  • 请注意,此答案会在某些输入上中断,例如“some-page.html-entities-tests.html”(真实世界示例)。更稳健的重写是: `if ($request_uri ~ ^/(.*)\\.html(\?|$)) { return 302 /$1$is_args$args; }` (3认同)