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匹配命令 ~ #波浪线表示执行一个正则匹配,区分大小写~* #表示执行一个正则匹配,不区分大小写^~ #^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配 ...
随机推荐
- 【康拓展开】及其在求全排列第k个数中的应用
题目:给出n个互不相同的字符, 并给定它们的相对大小顺序,这样n个字符的所有排列也会有一个顺序. 现在任给一个排列,求出在它后面的第i个排列.这是一个典型的康拓展开应用,首先我们先阐述一下什么是康拓展 ...
- MIT 6.828 JOS学习笔记8. Exercise 1.4
Lab 1 Exercise 4 阅读关于C语言的指针部分的知识.最好的参考书自然是"The C Programming Language". 阅读5.1到5.5节.然后下载poi ...
- MIT 6.828 JOS学习笔记6. Appendix 1: 实模式(real mode)与保护模式(protected mode)
在我们阅读boot loader代码时,遇到了两个非常重要的概念,实模式(real mode)和保护模式(protected mode). 首先我们要知道这两种模式都是CPU的工作模式,实模式是早期C ...
- C#对象序列化与反序列化
C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍.......................... ...
- 解决webstorm卡顿问题
webstorm强大的功能就不多做介绍了.但是它的缺点也显而易见:吃内存. 电脑配置稍低一点,运行webstorm就特别容易卡顿,特别是项目比较大的时候,那卡顿得不要不要的. 在我的笔记本8g内存 2 ...
- [BZOJ1501][NOI2005] 智慧珠游戏
Input 文件中包含初始的盘件描述,一共有10行,第i行有i个字符.如果第i行的第j个字符是字母”A”至”L”中的一个,则表示第i行第j列的格子上已经放了零件,零件的编号为对应的字母.如果第i行的第 ...
- 【水】基于ege的2048
不要问我ege怎么装 http://tieba.baidu.com/p/2227018541 好,现在我们装好了ege 开始写2048吧 没有算法,单纯模拟,不用讲解——这才叫[水]的含义 界面极度简 ...
- 【BZOJ】3427: Poi2013 Bytecomputer
题意: 给定一个长度为\(n\)的\(\{-1, 0, 1\}\)组成的序列,你可以进行\(x_i=x_i+x_{i-1}\)这样的操作,求最少操作次数使其变成不降序列.(\(n \le 100000 ...
- Python数据库迁移脚本(终极版)
上次的那几个脚本这次全部整合到了一起,而且后面发现了一个可以使用的ODBC包,于是这次采用的方式就很简单了,直接通过ODBC将InterBase数据库中的数据全部取出来之后通过Python的sqlal ...
- eclipse安装genymotion插件。
先发个我自己压缩的genymotion和VirtualBox,下载链接:http://pan.baidu.com/s/1o7wgJiU 1.在安装genymotion之后,打开eclipse,如下图操 ...