概述
location匹配顺序
示例配置代码
user root root;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
#worker_rlimit_nofile 655350;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
client_max_body_size 1024m;
#gzip on;
server {
listen 8090;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /aa-web {
#root /home/abc/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /aa-web/index.html;
}
location ^~ /aa-server {
proxy_pass http://192.168.1.80:18081;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
chunked_transfer_encoding off;
client_max_body_size 100m;
# rewrite ^/aa-server/?(.*)$ /$1 break;
#proxy_port off;
#proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
nginx有两层指令来匹配请求 URI 。第一个层次是 server 指令,它通过域名、ip 和端口来做第一层级匹配,当找到匹配的 server 后就进入此 server 的 location 匹配。
location 的匹配并不完全按照其在配置文件中出现的顺序来匹配,请求URI 会按如下规则进行匹配:
1、先精准匹配 = ,精准匹配成功则会立即停止其他类型匹配;
2、没有精准匹配成功时,进行前缀匹配。先查找带有 ^~ 的前缀匹配,带有 ^~ 的前缀匹配成功
则立即停止其他类型匹配,普通前缀匹配(不带参数 ^~ )成功则会暂存,继续查找正则匹配;
3、= 和 ^~ 均未匹配成功前提下,查找正则匹配 ~ 和 ~* 。当同时有多个正则匹配时,按其在配置文件中出现的
先后顺序优先匹配,命中则立即停止其他类型匹配;
4、所有正则匹配均未成功时,返回步骤 2 中暂存的普通前缀匹配(不带参数 ^~ )结果
location 支持的语法 location [=||*|^~|@] pattern { … },乍一看还挺复杂的,来逐个看一下。
以上规则简单总结就是优先级从高到低依次为(序号越小优先级越高):
1. location = # 精准匹配
2. location ^~ # 带参前缀匹配
3. location ~ # 正则匹配(区分大小写)
4. location ~* # 正则匹配(不区分大小写)
5. location /a # 普通前缀匹配,优先级低于带参数前缀匹配。
6. location / # 任何没有匹配成功的,都会匹配这里处理
location修饰符类型
「=」 修饰符:要求路径完全匹配
server {
server_name website.com;
location = /abcd {
[…]
}
}
- http://website.com/abcd匹配
- http://website.com/ABCD可能会匹配 ,也可以不匹配,取决于操作系统的文件系统是否大小写敏感(case-sensitive)。ps: Mac 默认是大小写不敏感的,git 使用会有大坑。
- http://website.com/abcd?param1¶m2匹配,忽略 querystring
- http://website.com/abcd/不匹配,带有结尾的/
- http://website.com/abcde不匹配
「~」修饰符:区分大小写的正则匹配
server {
server_name website.com;
location ~ ^/abcd$ {
[…]
}
}
^/abcd$这个正则表达式表示字符串必须以/开始,以$结束,中间必须是abcd
- http://website.com/abcd匹配(完全匹配)
- http://website.com/ABCD不匹配,大小写敏感
- http://website.com/abcd?param1¶m2匹配
- http://website.com/abcd/不匹配,不能匹配正则表达式
- http://website.com/abcde不匹配,不能匹配正则表达式
「~*」不区分大小写的正则匹配
server {
server_name website.com;
location ~* ^/abcd$ {
[…]
}
}
- http://website.com/abcd匹配 (完全匹配)
- http://website.com/ABCD匹配 (大小写不敏感)
- http://website.com/abcd?param1¶m2匹配
- http://website.com/abcd/ 不匹配,不能匹配正则表达式
- http://website.com/abcde 不匹配,不能匹配正则表达式
「^~」修饰符:前缀匹配
如果该 location 是最佳的匹配,那么对于匹配这个 location 的字符串, 该修饰符不再进行正则表达式检测。注意,这不是一个正则表达式匹配,它的目的是优先于正则表达式的匹配
查找的顺序及优先级
当有多条 location 规则时,nginx 有一套比较复杂的规则,优先级如下:
- 精确匹配 =
- 前缀匹配 ^~(立刻停止后续的正则搜索)
- 按文件中顺序的正则匹配 ~或~*
- 匹配不带任何修饰的前缀匹配。
这个规则大体的思路是
先精确匹配,没有则查找带有 ^~的前缀匹配,没有则进行正则匹配,最后才返回前缀匹配的结果(如果有的话)
案例分析
案例 1
server {
server_name website.com;
location /doc {
return 701; # 用这样的方式,可以方便的知道请求到了哪里
}
location ~* ^/document$ {
return 702; # 用这样的方式,可以方便的知道请求到了哪里
}
}
curl -I website.com:8080/document HTTP/1.1 702
按照上述的规则,第二个会有更高的优先级
案例2
server {
server_name website.com;
location /document {
return 701;
}
location ~* ^/document$ {
return 702;
}
}
curl -I website.com:8080/document
第二个匹配了正则表达式,优先级高于第一个普通前缀匹配
案例 3
server {
server_name website.com;
location ^~ /doc {
return 701;
}
location ~* ^/document$ {
return 702;
}
}
curl http://website.com/document HTTP/1.1 701
第一个前缀匹配^~命中以后不会再搜寻正则匹配,所以会第一个命中
案例 4
server {
server_name website.com;
location /docu {
return 701;
}
location /doc {
return 702;
}
}
curl -I website.com:8080/document 返回 HTTP/1.1 701,
server {
server_name website.com;
location /doc {
return 702;
}
location /docu {
return 701;
}
}
curl -I website.com:8080/document 依然返回 HTTP/1.1 701
前缀匹配下,返回最长匹配的 location,与 location 所在位置顺序无关
案例 5
server {
listen 8080;
server_name website.com;
location ~ ^/doc[a-z]+ {
return 701;
}
location ~ ^/docu[a-z]+ {
return 702;
}
}
curl -I website.com:8080/document 返回 HTTP/1.1 701
把顺序换一下
server {
listen 8080;
server_name website.com;
location ~ ^/docu[a-z]+ {
return 702;
}
location ~ ^/doc[a-z]+ {
return 701;
}
}
curl -I website.com:8080/document 返回 HTTP/1.1 702
正则匹配是使用文件中的顺序,找到返回
常见问题
1、location 路径替换
最后
以上就是玩命小海豚为你收集整理的Nginx location 匹配location匹配顺序的全部内容,希望文章能够帮你解决Nginx location 匹配location匹配顺序所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复