修改Nginx正则表达式,使其仅在某些情况下应用

时间:2012-10-21 06:18:32

标签: php regex node.js nginx

我正在创建一个混合的PHP / Node.js应用程序。对于PHP,我使用Yii框架。在Node.js中,我使用express。

PHP正在通过Nginx运行。我使用proxy_pass指令将以/ node开头的任何请求汇集到在端口3000上运行的节点服务器(例如server.com/node/api代理到server.com:3000/api。)

这在大多数情况下效果很好。但是,我的Nginx配置文件中的一个指令确保不存在对不存在的静态文件的请求不会传递给Yii。相反,返回一个简单的404错误。该指令的原始版本如下所示:

location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar|txt)$ {
    try_files $uri =404;
    #For production servers you can set expires header with a long period
    expires 3M;
}

该指令的问题在于Node.js提供了一些静态文件(特别是socket.io客户端)。当浏览器请求server.com/node/socket.io/socket.io.js时,上述规则被触发,Nginx返回404。

我想要做的是修改规则,以便只有当静态文件的请求前面没有/ node /时才返回404。我尝试了各种规则组合,但似乎都没有。在查阅了perl正则表达式文档之后,我认为这可能有用,但不是:

location ~* (?<!/node/)\.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar|txt)$ {
    try_files $uri =404;
    expires 3M;
}

我认为规则的负面/后面部分(?<!/node/)可以排除以/ node /开头的请求,但它没有。相反,规则会因为真正不存在的js文件和socket.io.js(以及Node.js提供的各种其他静态文件)而被触发。所以在这两种情况下我都得到404.

如何更改正则表达式,以便仅在请求不以/ node /?开头时才应用规则?

3 个答案:

答案 0 :(得分:7)

如果我正确地阅读了您的问题,那么您谈论的是不以 /node/开头的路径。这比匹配之前没有的东西要简单得多。这应该这样做:

location ~* ^(?!/node/).*\.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar|txt)$ {

我认为@Pogo几乎拥有它,但据我所知它location不包含服务器名称。正则表达式起始锚^匹配.com之后(在这种情况下)和第一个斜杠之前的位置。因此,^(?!/node/)可确保您的路径不以/node/开头。

答案 1 :(得分:1)

问题是,负面的后视在点前面看起来立即。不幸的是,据我所知,只有.NET支持可变长度的lookbehinds。一个解决方法是,扭转字符串,反转正则表达式并在末尾使用负向前瞻(可以是可变长度):

(?!.*/node/)

不幸的是,我现在无法写出完整的正则表达式,因为我正在打电话。

答案 2 :(得分:1)

我认为问题可能是因为,javascipt并不支持完全支持。您可以在开始时查看它是否不是/ node /然后继续。

所以,

.*com(?!/node/).*\.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar|txt)$

可能会帮到你。