nginx 匹配顺序

1,125 阅读3分钟

nginx 配置

nginx中主要包含 server 和 location 的配置.

比如URL:www.test.com/login/

  • server 管的是前半部分,即:www.test.com
  • location 管的是后半部分,即:/login/

一个nginx可以配置多个server,每个server可以配置多个location。

URL的前半部分控制选择哪一个server,后半部分控制选择哪一个location,最终决定往哪里去请求

server 匹配

server 匹配顺序:

  1. 精确匹配

  2. 通配符匹配:

    1. 通配符在前:*.test.com
    2. 通配符在后:www.test.
  3. 正则匹配

  4. 兜底规则

    1. default_server :优先选择 listen 配置项后有 default 或 default_server 的
    2. 默认 default_server :nginx加载的第一个 server_name,通常是站点配置目录下 ls -l 结果的第一个配置文件

location 匹配

location 格式:

  • 字符匹配规则 (location modifier)
  • uri 匹配规则
  • 路由转发 (大括号内的部分)
location [空格 | = | ~ | ~* | ^~ | @ ] /uri/ {  
   ... 
}

modifier

[空格 | = | ~ | ~* | ^~ | @ ]

主要包含以下类型:

  • 空格:直接为空格,则为不写location modifier。可以匹配制定patern开头的url,且url只能是普通字符,不能是正则表达式
  • = : 精确匹配
  • ~ :正则匹配,区分大小写
  • ~* :正则匹配,不区分大小写
  • ^~ :匹配普通字符,优先级比空格高。 ^是非的意思,也即不进行正则匹配。匹配的字符串越长,优先级越高
  • @ : 定义location,不能被外部client访问,只能被nginx内部配置指令访问

匹配优先级:

  • 精确匹配 > 字符串匹配(长>短) > 正则匹配(上>下)
  •  [=] > [^~] > [~/~*] > [空格]

几个关注点:

  • 字符匹配 是 前缀匹配,正则匹配 是 包含匹配
  • 正则匹配的优先级 取决于配置顺序,越精确优先级越高
  • 字符匹配 如果包含两个一致的「匹配字符串」,nginx会报错,因为识别到两者的匹配规则是一致的,存在冲突
  • @必须和url直接相连,其他修饰符 和 uri之间 可以包含空格,也可以不包含

示例

`# demo1`

`location / {`

`  ``return` `200 ``'404'``;`

`}`

 

`location ~ ``/hello` `{`

`  ``return` `200 ``'1'``;`

`}`

 

`location ^~ ``/hello` `{`

`  ``return` `200 ``'2'``;`

`}`

 

`location = ``/hello` `{`

`  ``return` `200 ``'3'``;`

`}`

 

`location ~* ``/hello` `{`

`  ``return` `200 ``'4'``;`

`}`

 

 

`————————————————————————`

`[root@VM_156_200_centos ~]``# curl 127.0.0.1/hello  #精确匹配,直接结束`

`3`

`[root@VM_156_200_centos ~]``# curl 127.0.0.1/hello11 #字符串匹配,并且最大长度的匹配是 ~^,直接结束`

`2`

`[root@VM_156_200_centos ~]``# curl 127.0.0.1/hello/22 #字符串匹配,并且最大长度的匹配是 ~^,直接结束`

`2`

`[root@VM_156_200_centos ~]``# curl 127.0.0.1/11/hello/ #字符串不匹配(前缀匹配),正则匹配有两个,取最上面的那个`

`1`

`[root@VM_156_200_centos ~]``# curl 127.0.0.1/11/Hello/ #字符串不匹配(前缀匹配),正则匹配有一个(大小写不敏感),取最上面的那个`

`4`

`[root@VM_156_200_centos ~]``# curl 127.0.0.1/11/Hell #都不匹配,有设置通用匹配,取通用匹配`

`404`

 

 

`#### demo2`

`location ``/images/test``.png {`

`return` `200 ``'1'``;`

`}`

 

`location ^~ ``/images/` `{`

`return` `200 ``'2'``;`

`}`

 

`location ~ ``/images/` `{`

`return` `200 ``'3'``;`

`}`

 

`location ~ ``/images/test``.png {`

`return` `200 ``'4'``;`

`}`

`______________________[root@VM_156_200_centos ~]``# curl http://127.0.0.1/images/test.png`

`3`

`[root@VM_156_200_centos ~]``# curl http://127.0.0.1/images/1`

`2`

uri

uri 主要是要匹配的路径,可以是精确的路径,也可以是正则表达式,nginx的正则表达式语法为PCRE www.runoob.com/php/php-pcr…

正则表达式(Regular Expression)本身是一种用于字符串处理、匹配和替换的强大工具,它并不依赖于特定的编程语言或库。
PCRE(Perl Compatible Regular Expressions)则是正则表达式的一个具体实现,特别是它兼容Perl语言中的正则表达式语法。
换句话说,PCRE是正则表达式的一种应用形式,它将正则表达式的抽象概念具体化为可以在各种编程语言中使用的库或函数集。

路由转发

常用的路由转发功能包含:

  • 返回状态码和值
  • 反向代理
  • rewrite

返回状态码 - return

location ~ /A.html {   
    return 301 https://$server_name/B.html; 
}

反向代理 - proxy_pass

location / {  
    proxy_set_header  X-Real-IP       $remote_addr;   
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;   
    proxy_pass https://foo.com; 
}

rewrite

# 所有 .cgi 结尾的都重定向到 .html 
location ~ .cgi$ {   
    rewrite ^(.*).cgi$ $1.html last;   
    return 301; 
}  

location ~ .html$ {   
    return 200 '1'; 
} 
___________

[root@VM_156_200_centos ~]#  curl http://127.0.0.1/api.cgi 
1

参考文档

juejin.cn/post/690862…

nestealin.com/d21bac89/