快速掌握Nginx(二) —— Nginx的Location和Rewrite
1 location详解
1.location匹配规则
Nginx中location的作用是根据Url来决定怎么处理用户请求(转发请求给其他服务器处理或者查找本地文件进行处理)。location支持正则表达式,配置十分灵活。我们可以在一个虚拟主机(nginx中的一个server节点)下配置多个location以满足如动静分离,防盗链等需求。
location语法是: location [=|~|~*|^~] /uri/ {… },具体解释如下表:
符号 |
含义 |
location = /url |
= :开头,表示精确匹配,uri必须完全一致才能匹配成功 |
location ^~ /Purl |
^~:Puri和请求url的开头相同就匹配成功,且不再去匹配正则,也属于普通匹配 |
location /Purl |
普通匹配,Purl和用户请求url的开头相同就匹配成功,如果有多个普通匹配都匹配成功则按最长的 。 如有location /static/,和oaction /static/img/ 当请求是www.mysite.com/static/img/1.jpg时,第二个location匹配的更长,所以和第二个loaction匹配成功。 |
location ~ reg |
~ :区分大小写的正则匹配 |
location ~* reg |
~* :不区分大小写的正则匹配 |
location的匹配顺序是: = /url > ^~ /Purl > /Purl > ~ 和 ~* ,具体流程如下图所示,需要注意:一般情况下,匹配成功了普通字符串location后还会进行正则表达式location匹配。两种情况除外:①使用“=”,即精准匹配,如果匹配成功就立即停止其他匹配;②使用“^~”前缀,这个前缀告诉nginx ,如果匹配成功不再进行正则匹配。
简单总结:
1. 先进行精准匹配,如果匹配成功,立即返回结果并结束匹配过程。
2. 进行普通匹配,如果有多个location匹配成功,将“最长前缀”的location作为临时结果(如果是 ^~类型的普通匹配成功则直接返回结果,结束匹配过程)。
3. 由上至下逐一进行正则匹配,一旦匹配成功1个,立即返回结果,并结束解析过程;如果没有一个正则匹配成功,那么将普通匹配的最长前缀location作为最终结果返回,并结束匹配过程。
2. 实际使用建议
实际使用中,个人觉得每个虚拟主机下(server节点下)至少有三个匹配规则定义,如下:
#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
proxy_pass http://tomcat:8080/
}
实际使用建议参考自:https://segmentfault.com/a/1190000002797606
2 rewrite详解
1 rewrite简单认识
rewrite模块即ngx_http_rewrite_module模块,主要功能是实现URI重定向。rewrite模块会通过正则匹配重写URI,然后内部跳转再匹配location,或者直接做30x重定向返回客户端。Nginx的rewrite功能需要PCRE的支持,PCRE是perl兼容正则表达式库。rewrite指令的语法十分简单如下:
rewrite将符合正则的内容替换为新的替代内容
rewrite <regex> <replacement> [flag];
关键字 正则 替代内容 flag标记 正 则: perl兼容正则表达式语句进行规则匹配
替代内容: 将正则匹配的内容替换成replacement
flag标记: rewrite支持的flag标记
-------------------------------------------------------------------------------
flag标记说明:
last #匹配完成后不再匹配当前环境下的其他rewrite指令,开始匹配新的location URI规则
break #匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
使用rewrite时也会用到,几个常用的指令汇总如下:
指令 |
使用范围 |
作用 |
if ( condition ){ // 符合条件执行} |
location,server |
条件判断。 = != 判断是否相等 ~ ~* 判断是否符合正则 -e !-e 判断文件,目录,符号链接是否存在 -d !-d 判断目录是否存在 -f !-f 判断文件是否存在 -x !-x 判断是否可执行 |
break |
server,location,if |
不再继续执行任何指令,直接退出规则的执行 |
return |
server,location,if |
结束规则的执行和返回状态码给客户端;如 return 403; |
set variable ‘value’ |
http,server,location,if |
新建变量,并赋值 ;如 set varx 'hello' |
一个简单的栗子,简单了解下rewrite:
server{
listen 80;
server_name www.mysite.com;
#在server中调转到 爱奇艺
#rewrite ^/(.*) https://www.iqiyi.com break;
location = /{
#location中跳转到百度
rewrite ^/(.*) http://www.baidu.com;
root html;
index index.html;
}
#日志记录
error_log logs/mysite.error.log error;
access_log logs/mysite.access.log main;
}
我们知道默认情况访问nginx的虚拟主机会展示nginx的欢迎界面,我们通过rewrite指令跳转到百度。输入虚拟机的IP,访问结果不再是nginx欢迎页,而是302跳转到百度如下:
2 rewrite的执行过程
server{
listen 80;
server_name www.mysite.com;
location = /{
#跳转到百度
rewrite ^/(.*) http://www.baidu.com;
#跳转到/test1
rewrite ^/(.*) /test1;
#跳转到/test2
rewrite ^/(.*) /test2;
root html;
index index.html;
}
location /test1{
return 401;
}
location /test2{
return 402;
} #日志记录
error_log logs/mysite.error.log error;
access_log logs/mysite.access.log main;
}
server进行上边的配置时,我们访问虚拟机IP 192.168.70.132,会跳转到百度页面,因为replacement包含了http协议名,不在执行后续的rewrite指令;
如果把第一个rewrite注释掉,会调整到402错误页,因为rewrite的最终结果时以最后一个匹配成功的为准,最后匹配到 rewite /test2指令,然后找到location /test2返回402错误码;
如果我们在rewrite ^?(.*) /test1后边加上last标记 ,表示不再匹配后边的rewrite,会跳到401错误页,url不变还是http://192.168.70.132;
如果我们在rewrite ^?(.*) /test1后边加上redirect 或者 permanent 标记 ,表示不再匹配后边的rewrite,会跳转到401错误页(redirect的跳转码为302,permanet的跳转码时301),url会改变成 http://192.168.70.132/test1;
如果我们在rewrite ^?(.*) /test1后边加上break标记 ,表示不再匹配任何规则,会跳转到404错误页;因为break标记不会再执行任何规则,所以不会再去找location test1,而是直接找 html/test1资源,所以出现404错误。
3 一些常用的全局变量
变量 |
含义 |
$args |
请求中的参数,同$query_string |
$content length |
请求头中的Content-length字段。 |
$content_type |
请求头中的Content-Type字段。 |
$document_root |
当前请求在root指令中指定的值。 |
$host |
请求主机头字段,否则为服务器名称。 |
$http_user_agent |
用户代理,一般为用户浏览器信息 |
$http_cookie |
客户端cookie信息 |
$limit_rate |
这个变量可以限制连接速率。 |
$request_method |
客户端请求的动作,通常为GET或POST。 |
$remote_addr |
客户端的IP地址。 |
$remote_port |
客户端的端口。 |
$remote_user |
已经经过Auth Basic Module验证的用户名。 |
$request_filename |
当前请求的文件路径,由root或alias指令与URI请求生成。 |
$scheme |
协议名(如http,https)。 |
$server_protocol |
请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 |
$server_addr |
服务器地址,在完成一次系统调用后可以确定这个值。 |
$server_name |
服务器名称。 |
$server_port |
请求到达服务器的端口号。 |
$request_uri |
包含请求参数的原始URI,不包含主机名,如”/user/getuser?id=100”。 |
$uri |
不带请求参数的当前URI,$uri不包含主机名,如”/user/getuser”。 |
$document_uri |
与$uri相同。 |
这里列举几个rewrite的简单栗子来帮助理解:
server{
listen 80;
server_name localhost;
location /{
#如果客户端IP是192.168.70.1,那么拒接响应
if ($remote_addr = 192.168.70.1){
return 403;
}
root html;
index index.html;
}
}
通过IP为192.168.70.1的电脑去访问时,结果如下:
#如果是google访问的,重定向到 html/chrome.html页面
location /{
if ($http_user_agent ~ Chrome){
rewrite ^.*$ /chrome.html;
break;
}
root html;
index index.html;
}
③ 文件不存在返回404,写的比较繁琐,主要是演示rewrite的用法
server{
listen 80;
server_name www.mysite.com;
location /{
#如果文件不存在,跳转到notfound,
if (!-f /usr/local/nginx/html/aaa.html){
rewrite ^/(.*) /notfound ;
}
root html;
index index.html;
}
location ~ /notfound {
return 404;
}
error_log logs/mysite.error.log error;
access_log logs/mysite.access.log main;
}
小结:loaction和rewrite是nginx中最核心的指令,通过location和rewrite我们可以实现动静分离/规范客户端url等功能,因为支持perl的正则表达式,用法十分灵活。这里简单做了一些总结,如果有不正确的地方请指出。
【1】https://www.cnblogs.com/coder-yoyo/p/6346595.html
【2】https://www.cnblogs.com/czlun/articles/7010604.html
【3】https://www.cnblogs.com/crazylqy/p/6892010.html
快速掌握Nginx(二) —— Nginx的Location和Rewrite的更多相关文章
- Nginx (二) Nginx的反向代理负载均衡以及日志切割
Nginx是一个高并发,高性能的服务器,可以进行反向代理以及网站的负载均衡.这些功能的运用都在配置文件中,也就是Nginx安装目录下的conf/nginx.conf. nginx.conf 1. 先来 ...
- Nginx配置请求转发location及rewrite规则
一个示例: location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] } location / { # 因为所有的地址都以 / 开头,所以这 ...
- 【原创】运维基础之Nginx(3)location和rewrite
nginx location =:精确匹配(必须全部相等) ~:大小写敏感,正则匹配 ~*:忽略大小写,正则匹配 ^~:只需匹配uri部分,精确匹配 @:内部服务跳转,精确匹配 优先级: Exact ...
- nginx(二)nginx的安装
下载 nginx官网下载地址 把源码解压缩之后,在终端里运行如下命令: ./configure make make install 默认情况下,Nginx 会被安装在 /usr/local/nginx ...
- Nginx(二) nginx 无法启动
有时候在客户端输入:nginx 但是终端会输出以下,显示启动失败 nginx: [emerg] bind() to 0.0.0.0:8080 failed (48: Address already i ...
- 使用Docker快速部署ELK分析Nginx日志实践(二)
Kibana汉化使用中文界面实践 一.背景 笔者在上一篇文章使用Docker快速部署ELK分析Nginx日志实践当中有提到如何快速搭建ELK分析Nginx日志,但是这只是第一步,后面还有很多仪表盘需要 ...
- Nginx教程(二) Nginx虚拟主机配置
Nginx教程(二) Nginx虚拟主机配置 1 虚拟主机管理 1.1 Nginx管理虚拟主机 虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每台虚拟主 ...
- nginx配置文件中的location理解
关于一些对location认识的误区 1. location 的匹配顺序是"先匹配正则,再匹配普通". 矫正: location 的匹配顺序其实是"先匹配普通,再匹配正则 ...
- 二.Nginx反向代理和静态资源服务配置
2018年03月31日 10:30:12 麦洛_ 阅读数:1362更多 所属专栏: nginx 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/M ...
随机推荐
- C# 直接引用js文件,调js里的数据
C# 直接引用js文件,调js里的数据 引入命名空间 using System.IO; string path = AppDomain.CurrentDomain.BaseDirectory + &q ...
- 二进制安装 mariadb
默认路径安装MySQL,Mariadb 非常简单,解压,配置权限,修改配置文件基本即可使用:自定义安装稍微有点麻烦,需要修改的地方稍微多点: 下面详细介绍自定义目录,二进制安装mariadb, 使用传 ...
- 64位Win7下Asp.net项目连接Oracle时报ORA-6413:连线未打开异常
当时小弟碰到这个问题的时候,也找了挺久的回答,但是回答都是模棱两可的说是因为()的问题,但是没有给出具体的解决方案,这里小弟就用一个比较笨的方法来解决这个问题. 第一种:就是使用本地IISWeb服务器 ...
- MacBook Pro 安装win7 64 成功安装过程总结
安装对象: MacBook Pro (13 英寸, 2010 年中) 中安装win7 64位操作系统(原版安装非Ghost),且只保留win7系统即可. 场景还原: 拿到笔记本时,笔记本中已无Mac ...
- RuntimeException和Exception区别
1.java将所有的错误封装为一个对象,其根本父类为Throwable, Throwable有两个子类:Error和Exception. 2.Error是Throwable 的子类,用于指示合理的应用 ...
- anaconda的scikit-learn报错It seems that scikit-learn has not been built
我们在导入sklearn时往往会报错. import sklearn Traceback (most recent call last): File "<stdin>" ...
- PYQT5登录界面跳转主界面方法
该问题,有很多种方法,但是很多方法要么这个有问题,要么那个有问题,最后终于找到一种没问题的方法.记录一下: 参考地址:https://www.jianshu.com/p/d18ff36a78d6?fr ...
- scrapy CrawlSpider解析
CrawlSpider继承自Spider, CrawlSpider主要用于有规则的url进行爬取. 先来说说它们的设计区别: SpiderSpider 类的设计原则是只爬取 start_urls 中的 ...
- P4013 数字梯形问题 网络流
题目描述 给定一个由 nn 行数字组成的数字梯形如下图所示. 梯形的第一行有 mm 个数字.从梯形的顶部的 mm 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至底的路径. 分别 ...
- SQL FIRST() 函数
FIRST() 函数 FIRST() 函数返回指定的字段中第一个记录的值. 提示:可使用 ORDER BY 语句对记录进行排序. SQL FIRST() 语法 SELECT FIRST(column_ ...