location介绍
location指令的功能是用来匹配不同的url请求,进而对请求做不同的处理和响应
location语法
语法:location [=|^~|~|~*|@] /uri/ { … }
介绍:
前缀 | 说明 |
---|---|
空 | location后没有参数直接跟着URI,表示前缀匹配,代表跟请求中的URI从头开始匹配; 如/ , 表示通用匹配,任何未匹配到其它location的请求都会匹配到, 类似于switch…case中的default语句 |
~ | 表示该规则是使用正则定义的,区分大小写; |
~* | 表示该规则是使用正则定义的,不区分大小写; |
^~ | 表示最大前缀匹配,不做正则匹配检查。如果匹配成功,就采用该规则,不再进行后续的查找(即不再匹配其他location)。多用来匹配目录; |
= | 表示进行普通字符精确匹配。也就是完全匹配。只有请求的url路径与后面的字符串完全相等时,才会命中; |
@ | 定义一个命名的 location,@定义的locaiton名字一般用在内部定向,例如error_page, try_files命令中 |
小结:
~
和~*
前缀表示正则location , 其他( 如=、^~和@, 无任何前缀
)属于普通location
测试
下面我们就一一测试下
测试/
先来配置下nginx, 可以在nginx.conf
主配置文件中http{...}
段中加上include servers/*;(include指令用于从外部文件中引入配置参数)
,如果有的话就直接下一步。 接着我们在同级目录下新建servers
文件夹,再新建一个配置文件如location.conf
, 配置如下:
server {
listen 80;
server_name 127.0.0.1;
location / {
return 400;
}
}
当然你也可以使用Nginx echo
模块(可以直接在nginx中直接输出字符串,方便用户在做nginx配置时进行调试)测试location
匹配优先级, 这里我们使用return
配置return
简单说明:
语法: return code [text];
return code URL;
return URL;
默认值: 无
上下文: server, location, if
该指令将结束执行直接返回指定的状态码到客户端。 其中非标准代码 444 将关闭连接而不发送响应头。
修改完后重启nginx
: nginx -s reload
测试结果:
curl命令 curl -I http://127.0.0.1:80/
结果如下:
HTTP/1.1 400 Bad Request
测试 curl -v http://127.0.0.1:80/xxx
结果依然是一样的
由于/
是通配的,匹配任何请求,因为所有请求都是以”/“开始,但它的优先级我们暂时还不知道, 我们可以再加上/documents
配置测试下:
测试/documents
增加配置
location / {
return 400;
}
location /documents {
return 401;
}
修改完后重启nginx
: nginx -s reload
curl命令 curl -I http://127.0.0.1:80/documents
结果如下:
HTTP/1.1 401 Unauthorized
如果存在多个普通前缀location,那如何匹配呢?
增加以下配置:
location /documents/word {
return 200;
}
修改完后重启nginx
: nginx -s reload
curl命令 curl -I http://127.0.0.1:80/documents/word
结果如下:
HTTP/1.1 200 OK
小结:
/
匹配所有以 / 开头的请求。但是如果有更长的同类型的表达式,则选择更长的表达式。即最大前缀匹配。
测试~* /documents
~* 表示该规则是使用正则定义的,不区分大小写;
location ~* /documents {
return 402;
}
修改完后重启nginx
: nginx -s reload
curl命令 curl -I http://127.0.0.1:80/documents
结果如下:
HTTP/1.1 402 Payment Required
从结果可以看出来正则的优先级要大于location /
和location /documents
测试~ /documents
~ 表示该规则是使用正则定义的,区分大小写;
location ~ /documents {
return 403;
}
修改完后重启nginx
: nginx -s reload
curl命令 curl -I http://127.0.0.1:80/documents
结果如下:
HTTP/1.1 402 Payment Required
看结果是匹配了 ~* /documents
;
现在我们改变下顺序:
location ~ /documents {
return 403;
}
location ~* /documents {
return 402;
}
修改完后重启nginx
: nginx -s reload
curl命令 curl -I http://127.0.0.1:80/documents
结果如下:
HTTP/1.1 403 Forbidden
此时结果就匹配了~ /documents
小结:
当同时有多个正则匹配时,按其在配置文件中出现的先后顺序优先匹配,命中则立即停止其他类型匹配;
测试^~ /documents/
^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功,就采用该规则,不再进行后续的查找(即不再匹配其他location);多用来匹配目录。
location ^~ /documents/ {
return 404;
}
修改完后重启nginx
: nginx -s reload
curl命令 curl -I http://127.0.0.1/documents/1
结果如下:
HTTP/1.1 404 Not Found
测试 = /documents
增加以下配置:
location = /documents {
return 405;
}
修改完后重启nginx
: nginx -s reload
curl命令 curl -I curl -I http://127.0.0.1/documents
结果如下:
HTTP/1.1 405 Not Allowed
小结:
= 表示进行普通字符精确匹配。也就是完全匹配。只有请求的url路径与后面的字符串完全相等时,才会命中; 匹配优先级最高
测试 @
@
定义一个命名的 location,@定义的locaiton名字一般用在内部定向,例如error_page, try_files命令中
如配置error_page, 增加以下配置:
location /500 {
error_page 500 = @index_error;
return 500;
}
location @index_error {
return 200;
}
修改完后重启nginx
: nginx -s reload
curl命令 curl -I curl -I http://127.0.0.1/500
结果如下:
HTTP/1.1 200 OK
配置try_files如下:
location / {
# ...
try_files $uri $uri/ @index;
index index.html index.htm;
}
location @index {
rewrite ^/(.*)$ / permanent;
}
匹配优先级
以上测试已经证明过, 结论: =
> ^~
> ~|~*
> /
优先级示例
配置项如下:
location = / {
# 仅仅匹配请求 /
# 规则A
}
location / {
# 匹配所有以 / 开头的请求。但是如果有更长的同类型的表达式,则选择更长的表达式。如果有正则表达式可以匹配,则优先匹配正则表达式。
# 规则B
}
location /documents/ {
# 匹配所有以 /documents/ 开头的请求。但是如果有更长的同类型的表达式,则选择更长的表达式。如果有正则表达式可以匹配,则优先匹配正则表达式。
# 规则C
}
location ^~ /images/ {
# 匹配所有以 /images/ 开头的表达式,如果匹配成功,则停止匹配查找。所以,即便有符合的正则表达式location,也不会被使用规则D
}
location ~* \.(gif|jpg|jpeg|png|js|css)$ {
# 匹配所有以 gif jpg jpeg结尾的请求。但是 以 /images/开头的请求,将使用规则D
# 规则E
}
请求匹配示例:
访问根目录/ -> 如http://localhost/ 将匹配规则A;
访问http://localhost/index.html -> 将匹配规则B;
访问http://localhost/documents/document.html -> 将匹配规则C;
访问http://localhost/images/1.gif -> 将匹配规则D;
访问http://localhost/static/index.css -> 将匹配规则E;
注意,以上的匹配和在配置文件中定义的顺序无关。
最后, 如有错误,欢迎各位大佬指点!感谢!
参考资料
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return
https://blog.csdn.net/weixin_43898125/article/details/108069874