Nginx之Location匹配规则
概述
经过多年发展,nginx凭借其优异的性能征服了互联网界,成为了各个互联网公司架构设计中不可获取的要素。Nginx是一门大学问,但是对于Web开发者来说,最重要的是需要能捋的清楚Nginx的请求路由配置。
Nginx的路由配置放在配置文件中的Location子节,下面我们来熟练掌握Location的配置。
语法规则
location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
location 为关键字 类似java中的case关键字,关键字后跟随可选的修饰符,然后是匹配规则(正则匹配和模式匹配),后面的代码块为请求处理或转发的逻辑。
修饰符
一共4种修饰符:
=
表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。~
表示该规则是使用正则定义的,区分大小写。~*
表示该规则是使用正则定义的,不区分大小写。^~
表示前缀匹配,在正则之前。如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
「=」 修饰符-完全匹配
特点:要求路径完全匹配
server {
server_name website.com;
location = /abcd {
[…]
}
}
http://website.com/abcd
匹配http://website.com/ABCD
可能会匹配 ,也可以不匹配,取决于操作系统的文件系统是否大小写敏感http://website.com/abcd?param1¶m2
匹配,忽略 querystringhttp://website.com/abcde
**不匹配
「~」修饰符-正则匹配
特点:区分大小写的正则匹配
server {
server_name website.com;
location ~ ^/abcd$ {
[…]
}
}
注意: ^/abcd$
这个正则表达式表示字符串必须以/
开始,以$
结束,中间必须是abcd
http://website.com/abcd
匹配(完全匹配)http://website.com/ABCD
不匹配,大小写敏感http://website.com/abcd?param1¶m2
匹配http://website.com/abcd/
不匹配,不能匹配正则表达式http://website.com/abcde
不匹配,不能匹配正则表达式
「~*」修饰符-正则匹配
特点:不区分大小写的正则匹配
server {
server_name website.com;
location ~* ^/abcd$ {
[…]
}
}
http://website.com/abcd
匹配 (完全匹配)http://website.com/ABCD
匹配 (大小写不敏感)http://website.com/abcd?param1¶m2
匹配http://website.com/abcd/
不匹配
,不能匹配正则表达式http://website.com/abcde
不匹配
,不能匹配正则表达式
「^~」修饰符-模式匹配
前缀匹配 如果该 location 是最佳的匹配,那么对于匹配这个 location 的字符串, 该修饰符不再进行正则表达式检测。注意,这不是一个正则表达式匹配,它的目的是优先于正则表达式的匹配
匹配过程
对请求的url序列化。例如,对%xx
等字符进行解码,去除url中多个相连的/
,解析url中的.
,..
等。这一步是匹配的前置工作。
location有两种表示形式,一种是使用前缀字符,一种是使用正则。如果是正则的话,前面有~
或~*
修饰符。
具体的匹配过程如下:
首先先检查使用前缀字符定义的location,选择最长匹配的项并记录下来。
如果找到了精确匹配的location,也就是使用了=
修饰符的location,结束查找,使用它的配置。
然后按顺序查找使用正则定义的location,如果匹配则停止查找,使用它定义的配置。
如果没有匹配的正则location,则使用前面记录的最长匹配前缀字符location。
基于以上的匹配过程,我们可以得到以下两点启示:
- 使用正则定义的location在配置文件中出现的顺序很重要。因为找到第一个匹配的正则后,查找就停止了,后面定义的正则就是再匹配也没有机会了。
- 使用精确匹配可以提高查找的速度。例如经常请求
/
的话,可以使用=
来定义location。
匹配规则
原则: 先精确匹配,没有则查找带有 ^~
的前缀匹配,没有则进行正则匹配,最后才返回前缀匹配的结果(如果有的话)
- 首先精确匹配 =
- 其次前缀匹配 ^~
- 其次是按文件中顺序的正则匹配
- 然后匹配不带任何修饰的前缀匹配。
- 最后是交给 / 通用匹配
- 当有匹配成功时候,停止匹配,按当前匹配规则处理请求
注意:前缀匹配,如果有包含关系时,按最大匹配原则进行匹配。比如在前缀匹配:location /dir01
与 location /dir01/dir02
,如有请求 http://localhost/dir01/dir02/file
将最终匹配到 location /dir01/dir02
匹配逻辑伪代码:
function match(uri):
rv = NULL
if uri in exact_match:
return exact_match[uri]
if uri in prefix_match:
if prefix_match[uri] is '^~':
return prefix_match[uri]
else:
rv = prefix_match[uri] // 注意这里没有 return,且这里是最长匹配
if uri in regex_match:
return regex_match[uri] // 按文件中顺序,找到即返回
return rv```
URL尾部的/
关于URL尾部的/
有三点也需要说明一下。第一点与location配置有关,其他两点无关。
- location中的字符有没有
/
都没有影响。也就是说/user/
和/user
是一样的。 - 如果URL结构是
https://domain.com/
的形式,尾部有没有/
都不会造成重定向。因为浏览器在发起请求的时候,默认加上了/
。虽然很多浏览器在地址栏里也不会显示/
。这一点,可以访问baidu验证一下。 - 如果URL的结构是
https://domain.com/some-dir/
。尾部如果缺少/
将导致重定向。因为根据约定,URL尾部的/
表示目录,没有/
表示文件。所以访问/some-dir/
时,服务器会自动去该目录下找对应的默认文件。如果访问/some-dir
的话,服务器会先去找some-dir
文件,找不到的话会将some-dir
当成目录,重定向到/some-dir/
,去该目录下找默认文件。可以去测试一下你的网站是不是这样的。
总结
location的配置有两种形式,前缀字符和正则。查找匹配的时候,先查找前缀字符,选择最长匹配项,再查找正则。正则的优先级高于前缀字符。
正则的查找是按照在配置文件中的顺序进行的。因此正则的顺序很重要,建议越精细的放的越靠前。
使用=
精准匹配可以加快查找的顺序,如果根域名经常被访问的话建议使用=
。
参考
Nginx之Location匹配规则的更多相关文章
- Nginx之location 匹配规则详解
有些童鞋的误区 1. location 的匹配顺序是“先匹配正则,再匹配普通”. 矫正: location 的匹配顺序其实是“先匹配普通,再匹配正则”.我这么说,大家一定会反驳我,因为按“先匹配普通, ...
- Nginx的location匹配规则
一 Nginx的location语法 location [=|~|~*|^~] /uri/ { … } = 严格匹配.如果请求匹配这个location,那么将停止搜索并立即处理此请求 ...
- nginx中location匹配规则介绍
一,匹配规则 1,= 表示精确匹配 例子:http://localhost/ 将匹配到 location = / {...} http://localhost/aaa 可以匹配到 location ...
- 前端开发掌握nginx常用功能之server&location匹配规则
nginx主要是公司运维同学必须掌握的知识,涉及到反向代理.负载均衡等服务器配置.前端开发尤其是纯前端开发来说对nginx接触的并不多,但是在一些情况下,nginx还是需要前端自己来搞:例如我们公司的 ...
- nginx多虚拟主机优先级location匹配规则及tryfiles的使用
nginx多虚拟主机优先级location匹配规则及tryfiles的使用 .相同server_name多个虚拟主机优先级访问 .location匹配优先级 .try_files使用 .nginx的a ...
- location 匹配规则 (NGINX)
转:https://moonbingbing.gitbooks.io/openresty-best-practices/ngx/nginx_local_pcre.html location 匹配规则 ...
- nginx教程1:location 匹配规则
worker_process # 表示工作进程的数量,一般设置为cpu的核数 worker_connections # 表示每个工作进程的最大连接数 server{} # 块定义了虚拟主机 liste ...
- Nginx日志参数、location匹配规则、设置密码
1.三个参数 a)$http_referer:记录此次请求是从哪个链接访问过来的: 是直接访问,还是从其他网站跳转过来的. 例如:访问:http://www.etiantian.com/,其页面首页是 ...
- Nginx的alias与root的用法区别和location匹配规则
1.alias与root的用法区别 最基本的区别:alias指定的目录是准确的,root是指定目录的上级目录,并且该上级目录要含有location指定名称的同名目录. location /abc/ { ...
随机推荐
- 环境变量jdk版本与java -version显示不一致
问题描述: 问题产生原因: 1.Path环境变量配置了Oracle 2.C:\windows\System32下,还有java.exe. 问题描述: 今天遇到一个小bug,我电脑环境变量配置的版本是j ...
- MacOS Big Sur开HiDPI
我自己的环境: 开启hidpi的目的是为了让显示更加细腻,代价是缩小了显示范围. 自己在网上看了很多帖子,也尝试了几种,有些方法已经不再适合Big Sur系统了,所以本文提供一种可用的,在Big Su ...
- DolphinScheduler1.3.2源码分析(二)搭建源码环境以及启动项目
前置依赖组件安装 找一台服务器,或者本地的虚拟机,然后在服务器上安装好jdk,zookeeper,mysql. 1.源码调试环境搭建 源码环境搭建可以参考DolphinScheduler官方网站的开发 ...
- LCA算法——倍增
概况 LCA(Lowest Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. 实现过程 预处理:通过dfs遍历,记录每个节点到根节点的距离dis ...
- Hbase Java API包括协处理器统计行数
package com.zy; import java.io.IOException; import org.apache.commons.lang.time.StopWatch; import or ...
- zjnu1786 PROSJEK(二分)
Description Sample Input 4 1 1 2 3 4 Sample Output 4.000000 题意:给你n个数,让你找到长度大于等于k的连续串的最大平均值. 思路:我们可以二 ...
- entity framwork修改指定字段
1.ef修改时指修改指定字段public void ChangePassword(int userId, string password) { var user = new User() { Id = ...
- CF1475-C. Ball in Berland
CF1475-C. Ball in Berland 题意: 一个班级有\(a\)个男生和\(b\)个女生,现在这个班级有\(k\)对男女愿意一起出席毕业典礼,这里注意\(k\)对男女中可能会有某个男生 ...
- LVS+Keepalived深度理解,阐述你不知道的坑点
1. LVS简介 1. 什么是LVS? LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统.本项目在1998年5月由章文嵩博士成立,是中国国内 ...
- 卸载vue2.9.6版本,安装新版本
1.检查vue安装目录(cmd中输入) where vue 2.删除目录中的关于vue的文件(可以将文件按时间排序,找到vue相关的文件删除) 3.检查vue是否还能找到 4.安装新版本的vue np ...