NGINX有条件重写无扩展名URL

时间:2019-03-20 16:01:54

标签: nginx url-rewriting

我正在尝试为客户端提供无扩展名的URL。系统网址将在导航元素和链接中不带扩展名的情况下生成,因此我将拥有看起来像这样的链接。

www.somesite.com
www.somesite.com/foo
www.somesite.com/foo/bar
www.somesite.com/bar/foo/barfoo

让我们假装一下,这些调用将被路由到可以处理定义的文件扩展名的代理,或者简单地为html页面(如果存在)提供服务。如果正确地重写了网址,那么我认为带有扩展名的正则表达式匹配的location命令应该可以正常工作。

所以我们在幕后。

www.somesite.com/index.abc
www.somesite.com/foo.def
www.somesite.com/foo/bar.abc
www.somesite.com/bar/foo/barfoo.def
...

使用Apache .htaccess,我可以通过首先测试具有所需文件类型的页面的存在来解决此问题。

RewriteCond %{REQUEST_FILENAME}.abc -f
RewriteRule ^(.*)$ $1.abc [L]

我还要确保目录浏览已关闭并且尾部斜杠将被删除

#ensure trailing slash is removed
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)(?:/)$ $1 [R=301,L]

对Apache来说都是一件好事,对我来说也相对直观,但这是NGINX,坦率地说,我不知道如何解决该用例。

我发现所有类似的用例都处理html&php(How to remove both .php and .html extensions from url using NGINX?),并仅使用try_files,直到它们落入命名位置,该位置以.php扩展名重写uri。如果只使用一种动态语言,而如果使用两种动态语言,则失败会很惨。

所以问题是我该如何在NGINX中执行类似的操作,例如可以使用.htaccess条件/上面的内容进行重写

任何帮助将不胜感激!

欢呼 加里

更新:

通过使用标准php方法,我已经能够使其“大部分”正常工作。问题是 www.somesite.com 被定向到 www.somesite.com/.php 而不是提供默认文档。尾部的斜杠也已正确删除。

所以回顾一下:

www.somesite.com - not working - www.somesite.com/.php
www.somesite.com/foo - working
www.somesite.com/foo/bar - working
www.somesite.com/bar/foo/barfoo - working

这是我的配置:

location / {
        index  index.php index.html
        autoindex off;

        #remove trailing slash
        rewrite ^/(.*)(?:/)$ /$1 permanent;

        #try html files or route to named location
        try_files $uri $uri.html @php;
    }

 location ~ \.php$ {
        ...
    }

 location @php {
        rewrite ^(.*)$ $1.php last;
    }

在其他帖子中,try_files块如下所示: try_files $ uri $ uri.html $ uri / @php; 问题是如果我添加 $ uri / 将适用于默认文档,例如投放 www.somesite.com ,但所有其他网址(例如 www.somesite.com/foo / www.somesite.com/foo/bar / >也是目录并且具有相同名称的文件,将被重定向到无穷大,而不是它们各自的页面。

1 个答案:

答案 0 :(得分:0)

假设您有三种处理无扩展URI的方法,则将需要三个atomic-print块。您可以使用location按类型测试文件是否存在,如果找不到该文件,则可以级联到链中的下一个try_files块。有关详细信息,请参见this document

例如:

location

第一个块处理文档根目录内的普通文件。您可能有一个root /path/to/document/root; location / { try_files $uri $uri.html $uri/ @php; } location @php { try_files $uri.php @proxy; fastcgi_pass ...; ... } location @proxy { proxy_pass ...; } 块来处理PHP文件,第二个块实际上是一个副本。第三块将其他所有内容发送到上游。