Nginx位置匹配除php以外的所有文件扩展名 [英] Nginx location match all file extensions except php

查看:691
本文介绍了Nginx位置匹配除php以外的所有文件扩展名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的nginx配置文件中包含以下内容,它可以工作,但是我不想列出每个文件扩展名.

I have the following in my nginx config file, it works, but I don't want to have to list every file extension.

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

是否有办法将其应用于除php文件之外的所有内容?

Is there a way to apply this to everything except php files?

更新了配置

主文件:

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;
}

推荐答案

PCRE库

Nginx使用C语言编写的 PCRE库 . 手册页 很大,有时很难理解,但是非常详细. 在其中,您会发现功能方面的前瞻性/落后之处,就像您在Perl中发现的那样.

The PCRE Library

Nginx uses the PCRE library written in C. There's a huge man page, a bit hard to understand sometimes but quite detailed. Among it, you will find the look ahead / look behind functionnalities as you would find them in Perl.

如果一个字符串的一部分没有/在表达式之前/之前,则正/负向前/向后允许匹配字符串.向后看表达式只限于固定的字符串,因为大多数实现不可能向后应用正则表达式,因为您需要知道要为此返回多少步骤.向前看显然不受此限制,因此您可以像平常一样使用正则表达式.

Positive/negative look ahead/behind allow to match a string if one part of it is/isn't followed/preceded by an expression. Look behind expressions are restricted to a fixed string because it's not possible for most implementations to apply a regular expression backwards as you need to know how many steps you go back for this. Look ahead doesn't obviously suffer from this limitations, so you can use a regular expression like you usually do.

这是手册页的相关部分:

Here's the relevant section of the man page :

LOOKAHEAD和LOOKBEHIND声明

LOOKAHEAD AND 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.

不幸的是,您无法通过向前看来捕获字符串的结尾.

Unfortunately you can't capture the end of the string with look ahead.

因此,我们的首次尝试是在字符串末尾使用否定性的回望:

So, our first attempt will be using negative look behind from the end of the string :

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

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

Which means "Only capture strings that don't end with .php". That's quite close from what we need already. But there's something more to add to make it work like expected.

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

Indeed, nothing guarantees that you will have a string containing a file extension at this point. It could rather be anything except ^.+\.php$. To make sure this is a real file suffix, the natural way to overhaul this limit is by using nested location blocks where the most restrictive part is the apex. So our configuration will now look like below.

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

就是这样!

这是我在帖子更新后针对您所面临的第二个问题的评论(其他URL上有404错误).

Here are my remarks after your post update for the second issue you are facing (404 errors on other URLs).

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

As ~ .+(?<!\.php)$ matches everything except \.php$ and locations are nested, you need to nest the location block / and transform it to a regex match :

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

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

    location ~ / {
        # your stuff
    }

} 

还请注意,由于try_files指令的最后一个参数是内部重定向或HTTP代码,因此您可能会遇到try_files $uri /images/default.gif;部分无限循环的情况.因此,如果/images/default.gif不能解析为文件,则请求将通过此位置块10次以上,直到nginx停止处理并返回HTTP500.因此将其更改为try_files $uri /images/default.gif =404;.

Also note that you can end up with an infinite loop with the try_files $uri /images/default.gif; part because the last paremeter of the try_files directive is an internal redirect or an HTTP code. So if /images/default.gif doesn't resolve to a file, the request will go trough this location block 10 more times until nginx stops the processing and return HTTP 500. So change it to try_files $uri /images/default.gif =404;.

这篇关于Nginx位置匹配除php以外的所有文件扩展名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆