基本配置

为了探究nginx的url配置规则,当然需要安装nginx。我使用了vagrant创建了一个虚拟环境的Ubuntu,通过apt-get安装nginx。这样就不会污染mac的软件环境。通过vragrant再创建一个项目进行实验。

/vagrant目录下创建了一个pro用于项目的根目录,同时配置nginx的配置文件(/etc/nginx/sites-enabled/pro.conf)

  pro  tree
.
├── 403.html
├── 404.html
├── index.html0 
directories, 3 files

pro.conf的配置如下,即监听本机的80端口。

server {
   listen 80 default_server;
   server_name localhost;    access_log /var/log/nginx/pro/access.log;
   error_log /var/log/nginx/pro/error.log;    error_page 404 /404.html;    root /vagrant/pro;
   index index.html index.htm; }

上述的配置并没有设置location,但是配置了root /vagrant/pro,访问http://192.168.33.10/将会返回/vagrant/pro/index.html

匹配模式

匹配语法

nginx的url匹配模式很强大,同时使用非常灵活,尤其是优先级的匹配,如果不寻找规律,不但很难掌握,而且容易犯晕。了解优先级之前,先看看匹配的配置语法,以及都有那些匹配模式。

匹配的语法还是很简单的:

location [ = | ~ | ~* | ^~ ] uri { ... }location @name { ... }

没错,就这么多,实际写在loacation中大概是这样的

location = / {

}
location  [指令模式] url匹配模式 {

}

指令模式指用于匹配的方式,即精确匹配,前缀匹配还是正则匹配,当然这个是可选的,如果不写,则退化成正常匹配或者全匹配。url匹配模式则需要匹配的url,可以看成是web开发中的路由。下面就分别介绍指令模式和匹配模式。

精确匹配

=指令用于精确字符匹配(模式),不能使用正则,区分大小写。为了直观的观察匹配命中的location,使用rewrite指令,用于转发。目前只要理解命中了就重定向到rewrite后面的url即可。

location = /demo {   
    rewrite ^ http://google.com;
}

上述的配置表示只有访问 http://192.168.33.10/demo 这样的url,才能跳转到google的页面。除此之外的任何地址都无法访问,那怕是访问http://192.168.33.10/demo/这个地址也��行。因为url匹配模式是/demo

修改 location:

location = /demo$ {   
    rewrite ^ http://google.com;
}

熟悉正则的同学初看会以为/demo$表示demo结尾的url,其实不然,这里的$符号也是url的一部分,只有访问http://192.168.33.10/demo$这个地址才能跳转。

前缀匹配

^~指令用于字符前缀匹配,和=精确匹配一样,也是用于字符确定的匹配,不能使用正则且区分大小写。和=不同的在于,^~指令下,访问的url无需url匹配模式一模一样,只需要其开头前缀和url匹配模式一样即可。

location ^~ /demo {   
    rewrite ^ http://google.com;
}

对于该模式(/demo),访问下列的地址都能匹配:

  • http://192.168.33.10/demo

  • http://192.168.33.10/demo/

  • http://192.168.33.10/demo/aaa

  • http://192.168.33.10/demo/aaa/bbb

  • http://192.168.33.10/demo/AAA

  • http://192.168.33.10/demoaaa

  • http://192.168.33.10/demo.aaa

只需要以/demo为前缀开头的url都能匹配。与该模式后的是否大小写无关。

^~不支持正则。模式/demo$中的$并不代表字符模式结束,而是一个是实实在在的$,只有访问/demo$开头的url才能匹配,http://192.168.33.10/demo则不再匹配。

模式/[0-9]emo也不代表正则中的http://192.168.33.10/0emohttp://192.168.33.10/5emo之类,只有访问以 /[0-9]emo开头url才行,例如http://192.168.33.10/[0-9]emohttp://192.168.33.10/[0-9]emo/aaa

前缀匹配通常用于匹配文件夹,如配置静态文件。

正则匹配

众所周知,nginx的url功能强大,配置灵活。字符匹配中,支持正则和不支持正则完全是两个境界。前面的两种方式都不能使用正则,未免让人觉得nginx有点虚夸。

实际上,nginx支持正则匹配。所使用的指令是~~*,前者表示使用正则,区分大小写,后者表示使用正则,不区分大小写。与前缀匹配一样,正则匹配也是只需匹配以url模式开头的即可。

location ~ /[0-9]emo {   
    rewrite ^ http://google.com;
}

对于上述的模式,可以匹配的url如下:

  • http://192.168.33.10/5emo

  • http://192.168.33.10/9emo

  • http://192.168.33.10/5emo/aaa

  • http://192.168.33.10/5emo/AAA

  • http://192.168.33.10/5emoaaa

只要是以正则表达式/[0-9]emo匹配的字符开头的url,都能匹配。

使用~*则不区分大小写

location ~ /[0-9]EmO {   
    rewrite ^ http://google.com;
}

下面的都能匹配

  • http://192.168.33.10/5emo

  • http://192.168.33.10/9Emo

  • http://192.168.33.10/5emo/Aaa

  • http://192.168.33.10/5eMoEaaa

正常匹配

正常匹配的指令为空,即没有指定匹配指令的即为正常匹配。其形式类似 /XXX/YYY.ZZZ正常匹配中的url匹配模式可以使用正则,不区分大小写。

location /demo {   
    rewrite ^ http://google.com;
}

上述模式指的是匹配/demo的url,下面的都能匹配

  • http://192.168.33.10/demo

  • http://192.168.33.10/demo/

  • http://192.168.33.10/demo/aaa

  • http://192.168.33.10/demo/aaa/bbb

  • http://192.168.33.10/demo/AAA

  • http://192.168.33.10/demoaaa

  • http://192.168.33.10/demo.aaa

正常匹配和前缀匹配的差别在于优先级。前缀的优先级高于正常匹配

全匹配

全匹配与正常匹配一样,没有匹配指令,匹配的url模式仅一个斜杠/

location / {   
    rewrite ^ http://google.com;
}

全匹配也可以配合 精确匹配和正则匹配一些指令,只不过这样的设定意义不大。通过都会有一个默认的location,这个就是全匹配。

命名匹配

命名匹配指的是使用@比绑定一个模式,类似变量替换的用法。

error_page 404 = @not_found

location @not_found {     
    rewrite http://google.com;
}

上述的作用是如果访问没有匹配的url会触发404指令,然后就匹配到@not_found 这个 location上。

匹配优先级

nginx的匹配优先级遵循一个大原则和两个小细节。

大原则是关于匹配模式的优先级:

精确匹配  >  前缀匹配  >  正则匹配  > 正常匹配  > 全匹配

小细节则是同一优先级中:

  • 细节一:正则匹配成功之后停止匹配,非正则匹配成功还会接着匹配。

  • 细节二:在所有匹配成功的url中,选取匹配度最大的url字符地址。

不同级匹配模式优先级原则

精确匹配 > 前缀匹配

=精确匹配的优先级最高,这与配置的先后顺序无关

location ^~ /demo{   
    rewrite ^ http://google.com;
} location = /demo {   
    rewrite ^ http://baidu.com;
}

访问

http://192.168.33.10/demo      -> baidu.comhttp://192.168.33.10/demo/ggg -> google.com

尽管前缀匹配也能匹配/demo这个地址,并且还先命中,可是=的优先级更高。

再把前缀匹配换成正则匹配

location ~ /demo{   
    rewrite ^ http://google.com;
} location = /demo {   
    rewrite ^ http://baidu.com;
}

访问结果仍然一样。精确匹配的优先级最高。

前缀匹配 > 正则匹配

location ~ /[ad]emo{   
    rewrite ^ http://google.com;
} location ^~ /demo {   
    rewrite ^ http://baidu.com;
}

上述两个模式中,第一个使用正则匹配,第二个使用前缀匹配,访问效果如下

http://192.168.33.10/demo      -> baidu.comhttp://192.168.33.10/aemo     -> google.com

由此可见,尽管也是正则匹配先命中规则,可以优先级低,还是让步给前缀匹配。

正则匹配 > 正常匹配

location /demo/aa{     
    rewrite ^ http://google.com;
} location ~ /[ad]emo {     
    rewrite ^ http://baidu.com;
}
http://192.168.33.10/demo/aa        -> baidu.com 
http://192.168.33.10/aemo/aa     -> baidu.com

访问/demo/aa的地址的时候,尽管前者位置在前,并且也匹配最长,可是大规则的优先级,还是要先进行后面的正则匹配。小细节也必须让步大规则。

正常匹配 > 全匹配

location / {   
    rewrite ^ http://google.com;
} location /demo {   
    rewrite ^ http://baidu.com;
}

访问结果

http://192.168.33.10          -> index.htmlhttp://192.168.33.10/         -> google.comghttp://192.168.33.10/demo        -> baidu.com  http://192.168.33.10/demo/aa  -> baidu.com

由此可见,全匹配的优先级最低。

同级匹配细节

同级的匹配需要注意两个关键细节,是否是正则匹配,是否是最长匹配。

非正则匹配

location /demo {   
    rewrite ^ http://google.com;
} location /demo/aa {   
    rewrite ^ http://baidu.com;
}

访问测试

http://192.168.33.10/demo     -> google.comhttp://192.168.33.10/demo/aa  -> baidu.com

第一个连接只匹配了第一个location,跳转google.com;第二个连接两者都匹配,可是第二个location的匹配字符更长,因此跳转了baidu.com。

把正常匹配换成前缀匹配的效果也一样。

location ^~ /demo {   
    rewrite ^ http://google.com;
}
 
location ^~ /demo/aa {   
    rewrite ^ http://baidu.com;
}

访问结果如下:

http://192.168.33.10/demo     -> google.comhttp://192.168.33.10/demo/aa  -> baidu.com

通过上面的测试,可见同级的非正则的匹配,匹配结果最长的location最终会被命中。其实这个很好理解,匹配的字符越多,优先级越大嘛。但是为什么这个原则要特指非正则的匹配呢?

正则匹配

正则匹配不适用最大匹配的原则,本质原因是因为正则一旦匹配了,就停止匹配其他location,因此正则匹配与配置的先后顺序有关。

location ~ /demo {   
    rewrite ^ http://google.com;
} location ~ /demo/aa {   
    rewrite ^ http://baidu.com;
}
http://192.168.33.10/demo/aa  -> http://google.com

nginx开始匹配location的模式,其中/demo已经匹配了http://192.168.33.10/demo/aa这个地址,因此停止搜索匹配其他的location。

下面更改一下上述配置的先后顺序:

location ~ /demo/aa {   
    rewrite ^ http://baidu.com;
} location ~ /demo {   
    rewrite ^ http://google.com;
}

访问测试:

http://192.168.33.10/demo/aa  -> http://baidu.com

由此可见,正则匹配与匹配最大长度无关,只与匹配的先后顺序有关。

归纳

通过上述两个模式的测试,我们对两个细节进行了倒序的推导。实际上使用记住两个细节会比较简单。判断同级的优先级归纳如下:

面对一个location,先判断是否是正则匹配,如果是正则匹配,遇到匹配的模式,则命中。如果不是正则,则把匹配的模式放到一边,继续往下阅读配置,阅读完毕所有的匹配模式,查看哪一种的匹配模式更长,则是最终命中的模式。

掌握nginx的location匹配优先级其实也不难,谨记一个原则两个细节,妈妈再也不用担心配错url啦。

总结

nginx的url配置是使用nginx最基本功能。nginx作为服务器,它可以接收请求,处理请求,都是基于客户端url访问。掌握url的配置要了解配置的几个指令(=^~)。熟悉每个匹配模式的特点。

了解模式之后,对于优先级的判定,只需记住一个大的规则和两个细节,就能从容的应对了。

掌握url的配置之后,更重要的是在location域中做请求的处理。比如常见的静态文件配置,请求转发(rewrite),负载均衡等。

Nginx高级应用之Location Url的更多相关文章

  1. Nginx高级应用之Location Url 配置

    原文地址:https://www.linuxidc.com/Linux/2017-03/141910.htm 基本配置 为了探究nginx的url配置规则,当然需要安装nginx.我使用了vagran ...

  2. Nginx 高级配置-变量使用

    Nginx 高级配置-变量使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.  nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用,变量可以分为内置变量和自定义变 ...

  3. Nginx 高级配置-第三方模块编译

    Nginx 高级配置-第三方模块编译 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 第三模块是对nginx 的功能扩展,第三方模块需要在编译安装Nginx 的时候使用参数--add ...

  4. Nginx 高级配置-状态页配置

    Nginx 高级配置-状态页配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 建议将nginx的监控状态的值通过zabbix或者Open-Falcon之类的监控工具来监控状态,并 ...

  5. Nginx优化之日志优化,URL访问控制,防盗链,及站点文件目录优化

    Nginx日志相关优化与安全 日志切割脚本如下: #!/bin #日志切割脚本 Date=`date +%Y%m%d` Bdir="/usr/local/nginx" Nginxl ...

  6. Nginx 的编译安装和URL地址重写

    本文转自:http://www.178linux.com/14119#rd?sukey=ecafc0a7cc4a741b573a095a3eb78af6b4c9116b74d0bbc9844d8fc5 ...

  7. nginx反向代理+缓存开启+url重写+负载均衡(带健康探测)的部署记录

    在日常运维工作中,运维人员会时常使用到nginx的反向代理,负载均衡以及缓存等功能来优化web服务性能. 废话不多说,下面对测试环境下的nginx反向代理+缓存开启+url重写+负载均衡(带健康探测) ...

  8. 关于header('location:url')的一些说明,php缓冲区

    网上搜索header('location:url')的用法,得到如下三个结论: 1. location和“:”号间不能有空格,否则会出错. 2. 在用header前不能有任何的输出. 3. heade ...

  9. nginx配置文件中的location理解

    关于一些对location认识的误区 1. location 的匹配顺序是"先匹配正则,再匹配普通". 矫正: location 的匹配顺序其实是"先匹配普通,再匹配正则 ...

随机推荐

  1. 2. 解决svn working copy locked问题

    解决办法: 产生这种情况大多是因为上次svn更新命令执行失败且被自动锁定了. 如果cleanup没有效果的话只好手动删除锁定文件. 就可以通过“运行”--“cmd”--cd 到svn项目的根目录下,然 ...

  2. [Writeup]奇怪的单点音

    [Writeup]奇怪的单点音 单点音韵律,感觉法继续 看题 一个wav文件,没啥好说的 听了一下,类似鸟叫的电子音,后面插了不规律的三次嘟嘟声 先排除摩斯电码吧(唯一知道的东西(σ゚∀゚)σ) 解法 ...

  3. Navicat for MySQL 安装和破解(完美)

    Navicat for MySQL 安装软件和破解补丁: 链接:https://pan.baidu.com/s/1oKcErok_Ijm0CY9UjNMrnA   密码:4xb1 navicat fo ...

  4. php 中文转拼音,可以只转首字母,可以设置utf8、gbk

    <?php class Pinyin { /** * 默认是gb编码,第二个参数随意设置即为utf8编 * @param type $isInitial 是否只返回首字母 * @return t ...

  5. django 之manytomany

    https://www.cnblogs.com/changbaishan/p/8056762.html https://blog.csdn.net/hpu_yly_bj/article/details ...

  6. JSP基本_JSTL

    自定义标签是,用户定义自己的处理的tag的机制. JSTL是,JSP用标准自定义标签.从JSTL Ver.1.2开始成为JavaEE5的子集.比较有名的是Glassfish.Tomcat上开发的话,需 ...

  7. 转: JS实现页面打印

    转载原文: http://shengren-wang.iteye.com/blog/1161367 1.js实现(可实现局部打印) <!--打印的实现1:start--> <inpu ...

  8. 高效Java敏感词、关键词过滤工具包_过滤非法词句

    敏感词.文字过滤是一个网站必不可少的功能,如何设计一个好的.高效的过滤算法是非常有必要的.前段时间我一个朋友(马上毕业,接触编程不久)要我帮他看一个文字过滤的东西,它说检索效率非常慢.我把它程序拿过来 ...

  9. 18.4 运行脚本 sudo ./launcher.sh 必须先给他权限 才能使用

    我们发现我们每次启动服务都要打一大堆命令,ng build --watch ,nodemon server.js ,等等 凡是重复的工作,我们要可以代码完成 要想运行它呢 你必须将你运行的上述(脚本中 ...

  10. eclipse 连接数据库记录

    两篇很好的文章介绍给大家: Eclipse使用JDBC方式连接SQLServer2016 通过Driver与DriverManager连接数据库 --------------------------- ...