Nginx匹配规则

学习Nginx一个很重要的部分就是location的匹配,而location的匹配包含多种形式,且具有一定的顺序。

模式

  1. location = /uri 表示精确匹配
  2. location ^~ /uri 表示匹配开头
  3. location ~ pattern 区分大小写的正则
  4. location ~* pattern 不区分大小写的正则
  5. location /uri 前缀匹配,但在正则之后
  6. location / 通用匹配

其中,匹配发生的顺序也是按照上面的顺序执行的,首先精确匹配然后前缀匹配,依次进行,最后如果都没有匹配上,就转到通用匹配。

验证

worker_processes  1;
error_log logs/error.log info;

events {
    worker_connections 1024;
}

http {
    server {
        listen 8080;
        
        location = / {
        echo "规则A";
        }
        location = /login {
        echo "规则B";
        }
        location ^~ /static/ {
        echo "规则C";
        }
        location ^~ /static/files {
            echo "规则X";
        }
        location ~ \.(gif|jpg|png|js|css)$ {
        echo "规则D";
        }
        location ~* \.png$ {
        echo "规则E";
        }
        location /img {
            echo "规则Y";
        }
        location / {
        echo "规则F";
        }
    }
}

一定要自己使用curl来测试一下,很快就能明白location的匹配规则,这样拿到一份nginx的配置,你就能很快的锁定和识别出需要的信息。

实践

这里借用一份配置,来看看在实际中应该如何配置。

# 直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
# 这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
    proxy_pass http://tomcat:8080/index
}

# 第二个必选规则是处理静态文件请求,这是 nginx 作为 http 服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}

# 第三个规则就是通用规则,用来转发动态请求到后端应用服务器
# 非静态文件请求就默认是动态请求,自己根据实际把握
# 毕竟目前的一些框架的流行,带.php、.jsp后缀的情况很少了
location / {
    proxy_pass http://tomcat:8080/
}

rewrite规则

nginx的rewrite部分是首先然我困惑的部分,但只要先弄明白正则规则,然后将rewrite理解为一次uri的跳转即可。

正则规则

小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。

例子

rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;这样一条rewrite规则的意思是,对于形如/images/ef/uh7b3/test.png的请求,要匹配到/data?file=test.png

判断

因为rewrite经常与if语句结合使用,所以这里必须说一下if语句的判断表达式和判断依据。

常用的判断表达式如下:

-f 和 !-f 用来判断是否存在文件
-d 和 !-d 用来判断是否存在目录
-e 和 !-e 用来判断是否存在文件或目录
-x 和 !-x 用来判断文件是否可执行

nginx自带会有很多的全局变量可供使用,举一个常见的例子:

例:http://localhost:88/test1/test2/test.php?k=v
$host:localhost
$server_port:88
$request_uri:/test1/test2/test.php?k=v
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php

比较完整的nginx内置变量列表可以参考使用 Nginx 内置绑定变量