Nginx位置匹配除php之外的所有文件扩展名

时间:2014-11-02 23:56:36

标签: nginx

我在我的nginx配置文件中有以下内容,它有效,但我不想列出每个文件扩展名。

location ~ \.(gif|jpg|png|css|js|ttf|woff|html|htm|unity3d) {
    try_files $uri /images/default.gif;
}

有没有办法将这个应用到除php文件之外的所有内容?

修改:更新了配置

主文件:

server{
    listen 80 default_server;

    server_name    _;
    root           /usr/share/nginx/html/$http_host;
    index          index.php index.html index.htm;

#    location ~ \.(gif|jpg|png|css|js|ttf|woff|html|htm|unity3d|tpl) {
#        try_files $uri /images/default.gif =404;
#    }

    location ~ .+(?<!\.php)$ {
        location ~ ^[^.]+\.[^.]+$ {
            try_files $uri /images/default.gif =404;
        }

        location ~ / {
            try_files $uri $uri/ /index.html;
            include /usr/share/nginx/conf/mission13.io.conf;
        }

    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

然后在包含的文件中:

if ($http_host = groups.mission13.io) {
    rewrite ^(.+)$ /index.php?path=$1;
}

1 个答案:

答案 0 :(得分:9)

PCRE库

Nginx使用C语言编写的 PCRE library 。 有一个巨大的 man page ,有时候有点难以理解但非常详细。 其中,你会发现前瞻/看后面的功能,就像在Perl中找到它们一样。

正面/负面向前/向后看

正/负前瞻/后退允许匹配字符串,如果其中一部分是/未跟随/前面的表达式。查看后面的表达式仅限于固定字符串,因为大多数实现都不可能向后应用正则表达式,因为您需要知道为此返回了多少步骤。向前看并没有明显受到这种限制,所以你可以像往常一样使用正则表达式。

以下是手册页的相关部分:

  

LOOKAHEAD和LOOKBEHIND ASSERTIONS

     (?=...)         positive look ahead
     (?!...)         negative look ahead
     (?<=...)        positive look behind
     (?<!...)        negative look behind

 Each top-level branch of a look behind must be of a fixed length.

不幸的是,你无法通过向前看捕获字符串的结尾。

了解行动

所以,我们的第一次尝试将在字符串末尾使用负面外观:

location ~ .+(?<!\.php)$ {
    ...
}

表示“仅捕获不以.php结尾的字符串”。这与我们已经需要的非常接近。但是还有一些东西可以让它像预期的那样工作。

嵌套位置

实际上,没有什么能保证您此时会有一个包含文件扩展名的字符串。除了^.+\.php$之外,它可能是任何。为了确保这是一个真正的文件后缀,检查此限制的自然方法是使用嵌套的位置块,其中最严格的部分是顶点。所以我们的配置现在如下所示。

location ~ .+(?<!\.php)$ {
    location ~ ^[^.]+\.[^.]+$ {
        try_files $uri /images/default.gif;
    }
}

就是这样!

您的第二个问题

以下是您在面对第二个问题的更新后发表的评论(其他网址上的404错误)。

由于~ .+(?<!\.php)$匹配除\.php$以外的所有内容并且位置已嵌套,您需要嵌套位置块/并将其转换为正则表达式匹配:

location ~ .+(?<!\.php)$ {

    location ~ ^[^.]+\.[^.]+$ {
        try_files $uri /images/default.gif;
    }

    location ~ / {
        # your stuff
    }

} 

另请注意,最终可能会出现try_files $uri /images/default.gif;部分的无限循环,因为try_files指令的最后一个参数是内部重定向或HTTP代码。因此,如果/images/default.gif未解析为文件,则请求将通过此位置块10多次,直到nginx停止处理并返回HTTP 500.因此将其更改为try_files $uri /images/default.gif =404;