Nginx location 匹配顺序整理
Nginx location模块整理
具体的Nginx安装就不在这里描述了,这里只是为了对location的描述
Nginx环境
a. 查看当前系统cat /etc/redhat-release
[root@nginx /]# cat /etc/redhat-release
CentOS release 6.7 (Final)
[root@nginx /]#
b. 查看系统内核uname –r
[root@nginx /]# uname -r
2.6.32-573.el6.x86_64
[root@nginx /]#
c. 安装的Nginx版本,/appliation/nginx/sbin/nginx -V
[root@nginx sbin]# ./nginx -V
nginx version: nginx/1.6.2
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix=/application/nginx1.6.2 --with-http_stub_status_module --with-http_ssl_module
[root@nginx sbin]#
location模块
Nginx location
location 指令的作用是根据用户请求的URI来执行不同的应用,URI就是根据用户请求到的网址URL进行匹配,匹配成功了进行相关的操作。
location语法
下面是官网的语法结构:
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default: —
Context: server, location
官网解释翻译和理解
下面会结合官网原文进行解释,以下英文部分均从官网摘抄:
http://nginx.org/en/docs/http/ngx_http_core_module.html#location
(翻译的不好勿喷)
Sets configuration depending on a request URI.
根据请求的URI进行配置
URI 变量是待匹配的请求字符串,
A location can either be defined by a prefix string, or by a regular expression.
Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching)
一个location可以用prefix string(前缀字符串)定义,也可以通过regular expression(正则表达式来定义)
通俗的说也就是:我们可以通过使用不同的前缀,表达不同的含义,对于不同的前缀可以分为两大类:普通location和正则location
符号:”~”表示uri包含正则,并且区分大小写
符号:“~*”表示uri包含正则,但不区分大小写
注意:如果你的uri用正则,则你的正则前面必须添加~或者~*,之前我在这里存在误区,以为可以不加~或者~*
To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.
Nginx服务器会首先会检查多个location中是否有普通的uri匹配,如果有多个匹配,会先记住匹配度最高的那个。然后再检查正则匹配,这里切记正则匹配是有顺序的,从上到下依次匹配,一旦匹配成功,则结束检查,并就会使用这个location块处理此请求。如果正则匹配全部失败,就会使用刚才记录普通uri匹配度最高的那个location块处理此请求。
If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.
当普通匹配的最长前缀匹配有符号“^~”的时候,就不会在匹配正则
直接使用当前匹配的这个location块处理此请求
Also, using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/” request happens frequently, defining “location = /” will speed up the processing of these requests, as search terminates right after the first comparison. Such a location cannot obviously contain nested locations.
使用符号“=”修饰符可以定义一个精确匹配的URI和位置,如果找到了一个精确的匹配,则搜索终止,例如,如果一个”/”请求频繁发生,定义“location =/”将加快这些请求的处理,一旦精确匹配只有就结束,这样的location显然不能包含嵌套location
这里我们说一下location / {} 和location =/ {}的区别:
“location / {}”是普通的最大前缀匹配,任何的uri肯定是以“/”开头,所以location / {} 可以说是默认匹配,当其他都不匹配了,则匹配默认匹配
根据上述官网内容进行总结
a. ”=”用于普通uri前,要求精确匹配,如果匹配成功,则停止搜索并用当前location处理此请求
b. ”~” 表示uri包含正则,并且区分大小写
c. “~*”表示uri包含正则,但不区分大小写
d. ”^~”表示在普通uri前要求Nginx服务器找到普通uri匹配度最高的那个location后,立即处理此请求,并不再进行正则匹配
e. ”^~”和“=”都可以阻止继续匹配正则location两者的区别:“^~”依然遵守最大前缀原则,然后“=”是需要严格匹配
关于location网上的一些误解
location 的匹配顺序是“先匹配正则,再匹配普通”
这是一个错误的结论,从上面官网的文章中我们可以知道:
先匹配普通uri,然后记住匹配度最高的那个(官网原话:To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered.)然后匹配正则,如果正则匹配则结束查找,如果正则不匹配,则匹配之前普通匹配中匹配度最高的那个将执行该请求(官网原话:Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.)
所以:location 的匹配顺序是“先匹配正则,再匹配普通” 这句话肯定是错误的,况且这里并没有包含”^~”和“=”
location 的执行逻辑跟 location 的编辑顺序无关。
这也是一种错误的理解,我们根据上述内容可以知道:
如果是普通uri 匹配,这个时候是没有顺序的,但是正则匹配则是有顺序的,是从上到下依次匹配,一旦有匹配成功,则停止后面的匹配。
那么顺序到底是怎么匹配呢?
我画了一个location匹配的逻辑图便于理解匹配的顺序规则
通过实验来验证出结果
对www.conf配置如下:
[root@nginx extra]# cat www.conf
server {
listen 80;
server_name www.zhaofan.com;
access_log logs/access_www.log;
root html/www;
location / {
return 401;
}
location = / {
return 402;
}
location /documents/ {
return 403;
}
location ^~ /images/ {
return 404;
}
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
}
[root@nginx extra]#
注意:
location ~* \.(gif|jpg|jpeg)$ {
return 500;
这个部分$前面不能有空格,否则会提示如下错误:
[root@nginx extra]# ../../sbin/nginx -s reload
nginx: [emerg] invalid location modifier "~*\.(gif|jpg|jpeg)" in /application/nginx1.6.2/conf/extra/www.conf:19
如果$后面没有空格,则会提示如下错误:
[root@nginx extra]# ../../sbin/nginx -s reload
nginx: [emerg] directive "location" has no opening "{" in /application/nginx1.6.2/conf/extra/www.conf:23
这些都是细节问题,一定要注意
实验一:登录nginx网站,我这里的直接打开:http://192.168.8.105/
可以看出这里是精确匹配
location = / {
return 402;
}
实验二:打开http://192.168.8.105/aaa/
这里可以看出因为都不匹配,所以最后匹配了location / {}
location / {
return 401;
}
实验三:打开http://192.168.8.105/1.gif
这里可以看出是匹配了正则
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
实验四:打开http://192.168.8.105/aaa/1.gif
这里依然是匹配正则
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
实验五:打开http://192.168.8.105/images/1.gif
location / {
return 401;
}
location = / {
return 402;
}
location /document/ {
return 403;
}
location ^~ /images/ {
return 404;
}
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
这里通过配置把实验三和实验四的对比就可以看出来因为普通匹配里有“^~”,并且匹配到了images,所以这个就是不进行正则匹配
location ^~ /images/ {
return 404;
}
实验六:“^~”遵守最大前缀原则
配置如下:
location / {
return 401;
}
location = / {
return 402;
}
location = /document/ {
return 403;
}
location ^~ /images/ {
return 404;
}
location /images/1/ {
return 501;
}
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
还是关注标红的地方,这个时候我们登陆:http://192.168.1.19/images/
结果如下:
从这里可以看出匹配了:
location ^~ /images/ {
return 404;
}
但是如果我们登陆:http://192.168.1.19/images/1/
结果如下;
这里匹配了:
location /images/1/ {
return 501;
}
从这里我们可以看出“^~”遵守最大匹配原则。
实验七:当最长匹配和精确匹配相同时
配置如下:
location / {
return 401;
}
location = / {
return 402;
}
location = /document/ {
return 403;
}
location ^~ /images/ {
return 404;
}
location /images/1/ {
return 501;
}
location = /images/1/ {
return 502;
}
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
登陆:http://192.168.1.19/images/1/
结果如下:
但是如果这个时候登陆:http://192.168.1.19/images/1/aaa/
结果如下:
从这里我们可以看出当精确匹配和最长匹配相同时,匹配的是精确匹配。
不在过多的做实验,根据上面的逻辑图应该可以解决碰到的问题了
Nginx location 匹配顺序整理的更多相关文章
- nginx location匹配顺序及CI框架的nginx配置
Nginx location匹配顺序如下: 用前缀字符串定义的location规则对URI进行匹配测试. =号定义了精确的前缀字符串匹配,如果发现精确匹配则使用当前规则.否则继续下一步匹配. 匹配其它 ...
- Nginx Location匹配顺序
理论部分 文字释义匹配规则如下: 略述: 1.nginx服务器首先在server块的多个location块中搜索是否有标准的uri和请求字符串匹配.如果有多个标准uri可以匹配,就匹配其中匹配度最高的 ...
- nginx location 匹配顺序
location 匹配的原型是这样的:location [=|~|~*|^~|@] /uri/ { … } “=”是精确匹配“@”是命名的location ,在正常的location 匹配中不会使用, ...
- nginx中location匹配顺序
一.location语法 语法: Syntax: location [ = | ~ | ~* | ^~ ] uri { ... } location @name { ... } Default: - ...
- [转载+整理]Nginx Location匹配规则
目录 规则语法 location 分类 匹配顺序: 扩展 location / {}和 location =/ {}的区别 测试 规则语法 语法 匹配规则 空 普通匹配(遵循最大前缀匹配规则, 优先度 ...
- [整理] Nginx Location 匹配规则
目录 规则语法 location 分类 匹配顺序: 扩展 location / {}和 location =/ {}的区别 如何快速测试 规则语法 语法 匹配规则 空 普通匹配(遵循最大前缀匹配规则, ...
- nginx location匹配规则
谢谢作者的分享精神,原文地址:http://www.nginx.cn/115.html location匹配命令 ~ #波浪线表示执行一个正则匹配,区分大小写~* #表示执行一个正则匹 ...
- 转:nginx location匹配规则
location匹配命令 ~ #波浪线表示执行一个正则匹配,区分大小写~* #表示执行一个正则匹配,不区分大小写^~ #^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配 ...
- Nginx Location 匹配
location匹配命令 ~ #波浪线表示执行一个正则匹配,区分大小写~* #表示执行一个正则匹配,不区分大小写^~ #^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配 ...
随机推荐
- Win10 UI介绍之Titlebar
活动状态 非活动状态 var titleBar = ApplicationView.GetForCurrentView().TitleBar; titleBar.BackgroundColor = C ...
- Android 笔记 day1
- Android 配置问题
安装好后需要更新
- Guava学习笔记(4):Ordering犀利的比较器
转自:http://www.cnblogs.com/peida/p/Guava_Ordering.html Ordering是Guava类库提供的一个犀利强大的比较器工具,Guava的Ordering ...
- tftp服务器的搭建
基于 红帽6的tftp搭建,当然其他系统搭建方法也大致一样 #mount /dev/cdrom /mnt/ 挂载安装光盘 不同光盘挂载用 fdisk -l 查看光盘 #rpm ...
- css 选择器优先级
优先级自上而下逐渐递减 1. 在属性后面使用 !important 会覆盖页面内任何位置定义的元素样式. 2.作为style属性写在元素内的样式 3.id选择器 4.类选择器 5.标签选择器 6.通配 ...
- HTML5新增的标签
结构性元素<header><footer>定义页眉(与<head>不一样)和页脚 <section>定义section<article> 定 ...
- ejabberd 在eclipse(erlide)中的配置、调试、运行
最近在折腾ejabberd,将ejabberd项目配置到eclipse中进行编译.调试等,现在将过程记下来,希望能帮助到需要的人. 准备 本次环境是在linux中进行,博主的linux是fedora2 ...
- 给备战NOIP 2014 的战友们的10条建议
应老胡要求,要写10条建议= = begin 1. 注意文件关联 比如 halt 前要close(input); close(output); 还有就是一定要打这两句话= = 2. 快排,大家都懂得. ...
- 百度地图 获取两点坐标之间的驾车距离(非直线距离) c#
百度接口了解: http://lbsyun.baidu.com/index.php?title=webapi/route-matrix-api-v2 起点与终点为多对多关系,如果你只想取两个坐标,那就 ...