Nginx localhost路由匹配规则
URI 即统一标识资源符,通用的 URI 语法格式如下:
scheme:[//[user[:password]@]host[:port]][/path][?query][#fragment]
格式说明如下:
- 在 Nginx 的应用场景中,URL 与 URI 并无明确区别。URI 标准(RFC3986)中约定,URL 是 URI 的一个子集;
- scheme 是 URI 请求时遵守的协议,常见的有 HTTP、HTTPS、FTP;
- host[:port] 是主机名与端口号,HTTP 协议的默认端口是 80,HTTPS 协议的默认端口是 443;
- [/path] 是访问路径与访问文件名;
- [?query] 是访问参数,访问参数以“?”开始作标识,由多个以“&”连接的 key=value 形式的字符串组成。
语法 | location [= | ~ | ~* | ^~ | @] URI |
位置 | server,location |
其中,[=||*|^~|@]部分称为 location 修饰语(Modifier),修饰语定义了与 URI 的匹配方式。URI 为匹配项,可以是字符串或正则表达式。
URI 匹配规则
uri变量是待匹配的请求字符串,可以不包含正则表达式,也可以包含正则表达式,那么nginx服务器在搜索匹配location的时候,是先使用不包含正则表达式进行匹配,找到一个匹配度最高的一个,然后在通过包含正则表达式的进行匹配,如果能匹配到直接访问,匹配不到,就使用刚才匹配度最高的那个location来处理请求。
无修饰语
修饰符 | |
解释 | location 后没有参数直接跟着 标准 URI,表示前缀匹配,代表跟请求中的 URI 从头开始匹配。 |
server {
location /abc {
...
}
}
以下访问:只要以前缀abc开始就可以匹配,?后的都是访问参数
http://192.168.204.131/abc/def
http://192.168.204.131/abc?p1=TOM
http://192.168.204.131/abc/
http://192.168.204.131/abcdef...
修饰语 "="
修饰符 | = |
解释 | 用于标准 URI 前,要求请求字符串与其精准匹配,成功则立即处理,nginx停止搜索其他匹配,Linux 系统下会区分大小写,Windows 系统下则不会 |
server {
location =/abc {
...
}
}
以下访问:只能完全匹配 abc; ?后的都是访问参数
#可以匹配
http://192.168.204.131/abc
http://192.168.204.131/abc?p1=TOM
#匹配不到
http://192.168.204.131/abc/
http://192.168.204.131/abcdef
http://192.168.204.131/abc/def
修饰语 "~ | ~*"
修饰符 | ~ | ~* |
解释 | 用于正则 URI 前,表示 URI 包含正则表达式,~ 区分大小写,~* 不区分大小写 |
server {
location ~ ^/ABCD$ {
...
}
}
server {
location ~* ^/abcd$ {
...
}
}
以下访问:
# ~ 匹配
http://192.168.204.131/ABCD
http://192.168.204.131/ABCD?name=tom
# ~ 不匹配
http://192.168.204.131/ABCD/
# ~* 匹配
http://192.168.204.131/aBcD
http://192.168.204.131/abcd?p1=TOM
# ~* 不匹配
http://192.168.204.131/abcd/
修饰语 "^~"
修饰符 | ^~ |
解释 | 用于标准 URI 前,并要求一旦匹配到就会立即处理,不再去匹配其他的那些个正则 URI,一般用来匹配目录;注意,这不是一个正则表达式匹配,它的目的是优先于正则表达式的匹配 |
server {
location ^~ /abc {
...
}
}
修饰语 "@"
修饰符 | @ |
解释 | @ 定义一个命名的 location,@ 定义的locaiton名字一般用在内部定向,例如error_page, try_files命令中。它的功能类似于编程中的goto。 |
server {
location @jump_to_error_page {
default_type text/plain;
return 200 "not found ";
}
error_page 404 =200 @jump_to_error_page;
}
表示没找页面或资源,但是我正确返回了200,并通知没找到。
匹配顺序
优先级 | 修饰符 | 解释 |
1 | location = | # 精准匹配 |
2 | location ^~ | # 带参前缀匹配 |
3 | location ~ | # 正则匹配(区分大小写) |
4 | location ~* | # 正则匹配(不区分大小写) |
5 | location /a | # 普通前缀匹配,优先级低于带参数前缀匹配 |
6 | location / | # 任何没有匹配成功的,都会匹配这里处理 |
案例分析
案例1
location /doc {
return 701;
}
location ~* ^/document$ {
return 702;
}
curl -i localhost/document 702
按照上述的规则,显然第二个正则匹配会有更高的优先级
案例2
location /document {
return 701;
}
location ~* ^/document$ {
return 702;
}
curl -i localhost/doucument 702
第二个匹配了正则表达式,优先级高于第一个普通前缀匹配
案例3
location ^~ /doc {
return 701;
}
location ~* /document {
return 702;
}
curl -i localhost/document 701
第一个前缀匹配 ^~ 命中以后不会再搜寻正则匹配,所以会第一个命中
案例4
location /docu {
return 701;
}
location /doc {
return 702;
}
location /my {
return 701;
}
location /myweb {
return 702;
}
curl -i localhost/document 701
curl -i localhost/doc 702
curl -i localhost/myweb 702
curl -i localhost /mywebm 702
前缀匹配下,返回最长匹配的 ,与 location 所在位置顺序无关
curl -i localhost/myw 701
前缀匹配下,字符串没达到最长匹配,返回短的 location;
案例 5
location ~* ^/doc[a-z]+ {
return 701;
}
location ~* ^/docu[a-z]+ {
return 702;
}
location ~* ^/myw[a-z]+ {
return 701;
}
location ~* ^/my[a-z]+ {
return 702;
}
curl -i localhost/document 701
curl -i localhost/myweb 701
可见正则匹配是使用文件中的顺序,先匹配成功的返回。
curl -i localhost/myw 702
当完全匹配,就使用完全匹配 location;
location 实际使用建议
直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理
这里是直接转发给后端应用服务器
location = / {
proxy_pass http://192.168.204.131:19901/index
}
第二个必选规则是处理静态文件请求,这是 nginx 作为 http 服务器的强项,有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用:
location ^~ /static/ {
root /html/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js)$ {
root /html/res/;
}
第三个规则就是通用规则,用来转发动态请求到后端应用服务器,非静态文件请求就默认是动态请求;
location / {
proxy_pass http://192.168.204.131:19901/
}