0%

nginx location的匹配方式

location的基本语法格式为:

1
location [=|~|~*|^~|@] pattern { ... }

[=|~|~*|^~|@] 被称作 location modifier(修饰器/前缀),这会定义 nginx 如何去匹配其后的 pattern ,以及该 pattern 的最基本的属性(简单字符串或正则表达式)

匹配顺序

  1. =前缀指令匹配,如果匹配成功,则停止其他匹配
  2. 字符串指令匹配,顺序是从长到短,匹配成功的location如果使用^~,则停止正则匹配
  3. 正则表达式指令匹配,按照配置文件里的顺序,成功就停止其他匹配
  4. 如果第三步中有匹配成功,则使用该结果,否则使用第二步结果
  1. 匹配的顺序是先匹配字符串,再匹配正则。字符串匹配顺序是根据配置中字符长度从长到短,与字符串配置的location顺序是无关的;但是需要注意的是正则按照配置文件里的顺序匹配。找到第一个比配的正则表达式将停止后续匹配。

  2. 一般情况下,匹配成功了字符串location后还会进行正则表达式location匹配。有两种方法改变这种行为:一种是使用=前缀,这时执行的是严格匹配,并且匹配成功后立即停止其他匹配,同时处理这个请求;另外一种是使用^~前缀,如果路径匹配那么不匹配正则。

匹配顺序为:

(location =)>(location 完整路径)>(location ^~路径)>(location ~,~*正则顺序)>(location 部分起始路径)>(/)

匹配模式

1
2
3
4
5
6
7
8
=   精确匹配(必须全部相等)
^~ uri以某个常规字符串开头,不是正则匹配
~ 区分大小写的正则匹配
~* 不区分大小写的正则匹配
@ 服务内部跳转(不会被client访问到,只能被内部配置指令所访问,比如 try_files or error_page)
!~ 对区分大小写的匹配取反
!~* 对不区分大小写的匹配取反
/ 通用匹配,如果没有其他匹配,任何请求都会被匹配到

匹配例子

  1. =精确匹配

    1
    2
    3
    4
    location = / {
    # 规则
    }
    # 则匹配到 `http://www.example.com/` 这种请求
  2. ~大小写敏感

    1
    2
    3
    4
    5
    location ~ /Example/ {
    # 规则
    }
    #http://www.example.com/Example/ [成功]
    #http://www.example.com/example/ [失败]
  3. ~*大小写忽略

    1
    2
    3
    4
    5
    location ~* /Example/ {
    # 规则
    }
    #http://www.example.com/Example/ [成功]
    #http://www.example.com/example/ [成功]
  4. ^~uri 开头匹配

    1
    2
    3
    4
    5
    location ^~ /abc/ {
    # 规则
    }
    #http://www.example.com/abc/a.jpg [成功]
    #http://www.example.com/abc/b.mp4 [成功]
  5. @nginx 内部跳转

    1
    2
    3
    4
    5
    6
    7
    8
     location /img/ {
    error_page 404 @img_err;
    }

    location @img_err {
    # 规则
    }
    #以 /img/ 开头的请求,如果链接的状态为 404。则会匹配到 @img_err 这条规则上。

常用的匹配

直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理:

1
2
3
location = / {
proxy_pass http://localhost:8080/index
}

处理静态文件请求,这是 nginx 作为 http 服务器的强项:

1
2
3
4
5
6
7
location ^~ /static/ {
root /webroot/static/;
}
# 或者
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}

通用规则,用来转发动态请求到后端应用服务器:

1
2
3
location / {
proxy_pass http://localhost:8080/
}