Location语法规则
一、 Location语法规则指令:location [ = | ~ | ~* | ^~ ] uri { ... } 或者location @name { ... }; 可存在位置:server, location1.1 先普通 location ,再正则 locationNginx 其实是“先匹配普通 location ,再匹配正则 location ”,但是普通 location 的匹配结果又
一、 Location语法规则
指令:location [ = | ~ | ~* | ^~ ] uri { ... } 或者 location @name { ... } ; 可存在位置: server, location
1.1 先普通 location ,再正则 location
Nginx 其实是“先匹配普通 location ,再匹配正则 location ”,但是普通 location 的匹配结果又分两种:一种是“严格精确匹配”,官方英文说法是“ exact match ”;另一种是“最大前缀匹配”,官方英文说法是“ Literal strings match the beginning portion of the query – the most specific match will be used. ”。我们做个实验:
例题 1 :假设 nginx 的配置如下
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
deny all;
}
location ~ \.html$ {
root /usr/share/nginx/html;
index index.html index.htm;
allow all;
}
}
当前目录结构如下
[root@web01 conf.d]# tree /usr/share/nginx/html
/usr/share/nginx/html
├── 50x.html
└── index.html
测试结果1
curl http://localhost/ 403 Forbidden
说明被匹配到location / {}了,原因很简单HTTP 请求 GET / 被“严格精确”匹配到了普通 location / {} ,则会停止搜索正则 location
测试结果2
curl http://localhost/index.html Welcome to nginx
说明没有被location /匹配,否则会 403 Forbidden ,但 /index.html 的确也是以“ / ”开头的,只不过此时的普通 location / 的匹配结果是“最大前缀”匹配,所以 Nginx 会继续搜索正则 location , location ~ .html$ 表达了以 .html 结尾的都 allow all; 于是接着就访问到了实际存在的 index.html 页面
测试结果3
curl http://localhost/index_notfound.html 404 Not Found
同样的道理先匹配 location / {} ,但属于“普通 location 的最大前缀匹配”,于是后面被“正则 location ” location ~ .html$ {} 覆盖了,最终 allow all ; 但的确目录下不存在index_notfound.html 页面,于是 404 Not Found
测试结果4
curl http://localhost/index_notfound.txt 403 Forbidden
说明先匹配上了 location / {…deny all;} 尽管属于“普通 location ”的最大前缀匹配结果,继续搜索正则 location ,但是 /index.txt 不是以 .html结尾的,正则 location 失败,最终采纳普通 location 的最大前缀匹配结果,于是 deny all 了
1.2 普通 location 的“显式”严格匹配和“ ^~ ” 前缀
上面我们演示的普通 location 都是不加任何前缀的,其实普通 location 也可以加前缀:“ ^~
”和“ =
”。其中“ ^~”的意思是“非正则,不需要继续正则匹配
”,也就是通常我们的普通 location ,还会继续搜索正则 location (恰好严格精确匹配除外),但是 nginx 很人性化允许配置人员告诉 nginx 某条普通 location ,无论最大前缀匹配,还是严格精确匹配都终止继续搜索正则 location ;而“ = ”则表达的是普通 location 不允许“最大前缀”匹配结果,必须严格等于,严格精确匹配。
server {
listen 80;
server_name localhost;
location ^~ / {
root /usr/share/nginx/html;
index index.html index.htm;
deny all;
}
location ~ \.html$ {
root /usr/share/nginx/html;
index index.html index.htm;
allow all;
}
}
测试结果1
curl http://localhost/index_notfound.html 403 Forbidden
先匹配 location ^~ / {} ,因为其是非正则,不需要继续正则匹配,所以直接停止继续匹配,进入 location ^~ / {}
1.3 普通 location 与编辑顺序无关
对于普通 location 指令,匹配规则是:最大前缀匹配(与顺序无关),如果恰好是严格精确匹配结果或者加有前缀“ ^~ ”或“ = ”(符号“ = ”只能严格匹配,不能前缀匹配),则停止搜索正则 location ;
配置 1.3.1
server {
listen 80;
server_name localhost;
location /prefix/ {
deny all;
}
location /prefix/mid/ {
allow all;
}
}
配置 1.3.2
server {
listen 80;
server_name localhost;
location /prefix/mid/ {
allow all;
}
location /prefix/ {
deny all;
}
}
测试结果:
请求 | 配置 3.1 结果 | 配置 3.2结果 |
---|---|---|
curl http://localhost:80/prefix/t.html | 403 Not Found | 403 Not Found |
curl http://localhost:80/prefix/mid/t.html | 404 Not Found | 404 Not Found |
结果表明:普通 location 的匹配规则是“最大前缀”匹配,而且与编辑顺序无关。
1.4 正则 location 与编辑顺序有关
对于正则 location 的匹配规则是:按编辑顺序逐个匹配(与顺序有关),只要匹配上,就立即停止后面的搜索。
配置 3.1
server {
listen 80;
server_name localhost;
location ~ \.html$ {
allow all;
}
location ~ ^/prefix/.*\.html$ {
deny all;
}
}
配置 3.2
server {
listen 80;
server_name localhost;
location ~ ^/prefix/.*\.html$ {
deny all;
}
location ~ \.html$ {
allow all;
}
}
测试结果:
请求 | 配置 3.1 结果 | 配置 3.2结果 |
---|---|---|
curl http://localhost:9090/regextest.html | 404 Not Found | 404 Not Found |
curl http://localhost:9090/prefix/regextest.html | 404 Not Found | 403 Not Found |
1.5 前缀@的使用
配置如下:
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
allow all;
}
#error_page 404 http://www.baidu.com # 直接这样是不允许的
error_page 404 = @fallback;
location @fallback {
proxy_pass http://www.baidu.com;
}
}
上述配置文件的意思是:如果请求的 URI 存在,则本 nginx 返回对应的页面;如果不存在,则把请求代理到baidu.com 上去做个弥补(注: nginx 当发现 URI 对应的页面不存在, HTTP_StatusCode 会是 404 ,此时error_page 404 指令能捕获它)。
二、 root和alias的区别
指令:root path ;可存在位置:http、server、location、if
默认值:root html
指令:alias path;可存在位置:location
alias是一个目录别名的定义,root则是最上层目录的定义。使用root时,会到root + location 寻找资源;使用alias时,会到alias后定义的目录中找资源;
alias后面必须要用“/”结束,否则会找不到文件的。而root则可有可无
location /images {
root /data/w3;
}
- 访问:http://localhost:9090/images/是访问/data/w3/images/index.html文件
location /images/ {
alias /data/w3/images/;
}
- 访问:http://localhost:9090/images/是访问/data/w3/index.html文件
更多推荐
所有评论(0)