Web服务器群集:Nginx之Rewrite重写

news2024/11/17 2:44:44

目录

一、理论

1.Nginx正则表达式

2.location匹配

3.rewrite重写

二、实验

1.基于域名的跳转

2.基于客户端 IP访问跳转

3.基于旧域名跳转到新域名后面加目录

4.基于参数匹配的跳转

5.基于目录下所有 php结尾的文件跳转

6.基于最普通一条url请求的跳转

三、总结


一、理论

1.Nginx正则表达式

(1)元字符及说明

^ :匹配输入字符串的起始位置
$ :匹配输入字符串的结束位置
* :匹配前面的字符零次或多次。如“ab*”能匹配“a”及“ab”、“abb”
+ :匹配前面的字符一次或多次。如“ab+”能匹配“ab”及“abb”、“abbb”,但不能匹配“a”
? :匹配前面的字符零次或一次,例如“ab(cd)?”能匹配“ab”或者“abcd”,”?”等效于”{0,1}”
. :匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式
\ :将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$”
\d :匹配纯数字
{n} :重复 n 次
{n,} :重复 n 次或更多次
{n,m} :重复 n 到 m 次
[] :定义匹配的字符范围
[c] :匹配单个字符 c
[a-z] :匹配 a-z 小写字母的任意一个
[a-zA-Z0-9] :匹配所有大小写字母或数字
() :表达式的开始和结束位置
| :或运算符

2.location匹配

(1)概念

在Nginx定义的每一个server中,还可以定义多个不同的location。这些不同的location根据请求中的URI的不同对HTTP请求进一步细分,提供不同的处理方法和服务。比如,根据请求中的URI不同,对于有些服务Nginx可以通过提供本地静态文件,而对于另外的动态内容请求可以转发到另外的动态服务进程中。

在实际的成产环境中,一个server 中可以定义非常多的location。而且在定义location时,不同的前缀可以对匹配的结果产生不同影响。如何正确地配置生产环境中总多location就变成一项很复杂的任务。

(2)分类

location可分为三类:

表1 location分类

类别代码
精准匹配location = / {…}
一般匹配location / {…}
正则匹配location ~ / {…}

(3)常用匹配规则

表2 常用匹配规则

规则描述
=进行普通字符精确匹配,也就是完全匹配
^~表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其它 location
~区分大小写的匹配
~*不区分大小写的匹配
!~区分大小写的匹配取非
!~*不区分大小写的匹配取非

(4)匹配优先级

表3 匹配优先级

优先级匹配
1精确匹配 =
2前缀匹配 ^~
3按文件中顺序的正则匹配 ~或~*
4匹配不带任何修饰的前缀匹配(一般匹配)
5交给 / 通用匹配

(5)匹配流程

location匹配的核心原则,是最长匹配,具体流程是:

表4 匹配流程

流程顺序具体流程
1先对前缀location执行最长前缀匹配。
2若最长前缀location前携带有=或者^~,那么使用此location配置块处理请求,不再进行正则匹配。对于=前缀,要求完全相等,对于^~前缀,只有最长匹配前有^~符号,才能跳过正则表达式。
3按server{ }中正则表达式的出现顺序,依次匹配。成功后就选中此location。正则表达式的查找是按照在配置文件中的顺序进行的。因此正则的顺序很重要,建议越精细的放的越靠前。
4若所有正则表达式皆未匹配上,则使用第1步中检索出的最长前缀location处理请求。
5如果在第1步中也没有匹配到最长location,则返回404。

(6)匹配应用

表5 匹配应用说明

配置文件匹配过程
location = / {
    [ configuration A ]
}
请求/精准匹配A,不再往下查找。
location / {
    [ configuration B ]
}
请求/index.html匹配B。首先查找匹配的前缀字符,找到最长匹配是配置B,接着又按照顺序查找匹配的正则。结果没有找到,因此使用先前标记的最长匹配,即配置B。
请求/documents/about.html匹配B。因为B表示任何以/开头的URL都匹配。在上面的配置中,只有B能满足,所以匹配B。
location /user/ {
    [ configuration C ]
}
请求/user/index.html匹配C。首先找到最长匹配C,由于后面没有匹配的正则,所以使用最长匹配C。
location ^~ /images/ {
    [ configuration D ]
}

请求/images/1.jpg匹配D。首先进行前缀字符的查找,找到最长匹配D。但是,特殊的是它使用了^~修饰符,不再进行接下来的正则的匹配查找,因此使用D。这里,如果没有前面的修饰符,其实最终的匹配是E。

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}
请求/user/1.jpg匹配E。首先进行前缀字符的查找,找到最长匹配项C,继续进行正则查找,找到匹配项E。因此使用E。
(1)location = / {}
=为精确匹配 / ,主机名后面不能带任何字符串,比如访问 / 和 /data,则 / 匹配,/data 不匹配
再比如 location = /abc,则只匹配/abc ,/abc/或 /abcd不匹配。若 location  /abc,则即匹配/abc 、/abcd/ 同时也匹配 /abc/

(2)location / {}
因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 比如访问 / 和 /data, 则 / 匹配, /data 也匹配,
但若后面是正则表达式会和最长字符串优先匹配(最长匹配)

(3)location /documents/ {}
匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的正则表达式没有匹配到时,才会采用这一条

(4)location /documents/abc {}
匹配任何以 /documents/abc 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的正则表达式没有匹配到时,才会采用这一条

(5)location ^~ /images/ {}
匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条

(6)location ~* \.(gif|jpg|jpeg)$ {}
匹配所有以 gif、jpg或jpeg 结尾的请求
然而,所有请求 /images/ 下的图片会被 location ^~ /images/ 处理,因为 ^~ 的优先级更高,所以到达不了这一条正则

(7)location /images/abc {}
最长字符匹配到 /images/abc,优先级最低,继续往下搜索其它 location,会发现 ^~ 和 ~ 存在

(8)location ~ /images/abc {}
匹配以/images/abc 开头的,优先级次之,只有去掉 location ^~ /images/ 才会采用这一条

(9)location /images/abc/1.html {}
匹配/images/abc/1.html 文件,如果和正则 ~ /images/abc/1.html 相比,正则优先级更高

(7)匹配规则定义

实际网站使用中,至少有三个匹配规则定义:

① 直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。 这里是直接转发给后端应用服务器了,也可以是一个静态首页。

location = / {
    proxy_pass http://tomcat_server/;
}

② 处理静态文件请求,这是nginx作为http服务器的强项。有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用。

location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(html|gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}

③ 通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器
非静态文件请求就默认是动态请求。

location / {
    proxy_pass http://tomcat_server;
}

(8)数据结构

与location匹配相关的数据结构有:ngx_http_core_loc_conf_s,ngx_listening_t, ngx_http_port_t, ngx_http_in_addr_t, ngx_http_addr_conf_t, ngx_http_server_name_t, ngx_http_conf_port_t, ngx_http_conf_addr_t, ngx_http_request_t, ngx_http_connection_t,ngx_http_location_queue_t等。它们的关联关系如下图所示:

结构体功能

ngx_http_core_loc_conf_s

ngx_http_core_loc_conf_s结构对应一个location块的配置,结构中的named, noname, exact_match和noregex flag用来区分location定义中的几个修饰符。
ngx_http_location_queue_t结构体ngx_http_location_queue_t用于临时保存location的队列。其中如果location是exact_match, regex, named或者noname类型的,则会把location结构存放到exact成员变量中。如果是非exact类型,则存放到inclusive变量中。

(9)源码分析

与配置平面有关的逻辑就是解析location指令并且构建用于查找的URI数据结构。

指令location的解释函数是ngx_http_core_location。

函数流程为:

流程顺序流程内容
1完整性检测,比如判断locations queue是否为空,如果是空则直接返回。
2因为location可以嵌套,所以,函数ngx_http_init_locations递归调用,去处理嵌套情况。
3调用ngx_http_join_exact_locations把location queue中将当前虚拟主机中 URI字符串完全一致的exact 和inclusive 类型的location 进行合并。
4调用ngx_http_create_locations_list把locations queue变成locations list。如下图所示就是ngx_http_create_locations_list调用前后的效果。

调用函数ngx_http_create_locations_tree,在上述创建的list的基础上,进一步生成查找树。首先确定locaiton队列的中间节点,然后从中间节点把location分成两部分。分别再构造左右子树。最后把inclusive类型的location放入到成员tree中。

ngx-location-create-locations-tree调用前后的效果:

3.rewrite重写

(1)概念

rewrite功能就是使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记实现URL重写以及重定向。

rewrite只能放在server{},location{},if{}中,并且默认只能对域名后面的除去传递的参数外的字符串起作用。

(2)rewrite 跳转场景

① URL看起来更规范、合理;

② 企业会将动态URL地址伪装成静态地址提供服务;

③ 网址换新域名后,让旧的访问跳转到新的域名上;

④ 服务端某些业务调整。

备注:

URL是一个具体路径/位置;

URI是一个拥有相同类型/特性的对象集合;

URN用名称定位。

(3)rewrite 跳转实现

原理图:

 

(4)rewrite 实际场景

(5)rewrite正则表达式

(6)rewrite语法格式

rewrite <regex> <replacement> [flag];

(7)rewrite执行顺序

① 执行server块里面的rewrite指令

② 执行location匹配

③ 执行选定的location中的rewrite指令

(8)flag标记说明

表4 flag标记说明

标记说明
last本条规则匹配完成后,继续向下匹配新的location URI规则,一般用在 server 和 if 中
break本条规则匹配完成即终止,不再匹配后面的任何规则,一般使用在 location 中
redirect返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

(9)rewrite和location比较

从功能看 rewrite 和 location 似乎有点像,都能实现跳转,主要区别于rewrite是在同一域名内更改获取资源的路径,而 loction 是对一类路径做控制访问或反向代理,还可以proxy_pass到其他机器。

二、实验

1.基于域名的跳转

公司旧域名www.david.com有业务需求变更,需要使用新域名www.jack.com代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变。

vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.david.com;	  #域名修改	
	charset utf-8;
	access_log  /var/log/nginx/www.david.com.access.log;	#日志修改
	location / {
	#添加域名重定向
        if ($host = 'www.david.com'){			     #$host为rewrite全局变量,代表请求主机头字段或主机名
			rewrite ^/(.*)$ http://www.jack.com/$1 permanent;	#$1为正则匹配的内容,即域名后边的字符串
        }
        root   html;
        index  index.html index.htm;
    }
}

2.基于客户端 IP访问跳转

公司业务新版本上线,要求所有 IP 访问都显示一个固定维护页面,只有公司 IP :192.168.204.200访问正常。

vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.david.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/www.david.com-access.log  main;		#日志修改

	#设置是否合法的IP标记
    set $rewrite true;						#设置变量$rewrite,变量值为boole值true
    #判断是否为合法IP
	if ($remote_addr = "192.168.204.200"){	#当客户端IP为192.168.204.150时,将变量值设为false,不进行重写
        set $rewrite false;
    }
	#除了合法IP,其它都是非法IP,进行重写跳转维护页面
    if ($rewrite = true){					#当变量值为true时,进行重写
        rewrite (.+) /weihu.html;			#重写在访问IP后边插入/weihu.html
    }
    location = /weihu.html {
        root /var/www/html;					#网页返回/var/www/html/weihu.html的内容
    }
	location / {
        root   html;
        index  index.html index.htm;
    }
}

3.基于旧域名跳转到新域名后面加目录

访问 http://www.david.com,现在需要将这个域名下面的访问都跳转到http://www.david.com/center

vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.david.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/david.com-access.log;
	#添加
	location /post {
        rewrite (.+) http://www.jack.com/mcure$1 permanent;		#这里的$1为位置变量,代表/post
    }
	
	location / {
        root   html;
        index  index.html index.htm;
    }
}

4.基于参数匹配的跳转

vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.david.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/david.com-access.log  main;
	
	if ($request_uri ~ ^/100-(100|200)-(\d+).html$) {
        rewrite (.+) http://www.david.com permanent;
    }

	location / {
        root   html;
        index  index.html index.htm;
    }
}

5.基于目录下所有 php结尾的文件跳转

vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.david.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/david.com-access.log  main;
	
location ~* /upload/.*\.php$ {
    rewrite (.+) http://www.david.com permanent;
}

location / {
    root   html;
    index  index.html index.htm;
   }
}

6.基于最普通一条url请求的跳转

vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.david.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/david.com-access.log  main;
	
    location ~* ^/abc/123.html {
        rewrite (.+) http://david.com permanent;
    }

	location / {
        root   html;
        index  index.html index.htm;
    }
}

三、总结

匹配server和location是Nginx进行请求转发的核心过程。把某一个请求正确匹配到server和location以后,就可以通过server和location的配置开始对此请求开始服务了。对于location的匹配,为了提高匹配效率,Nginx把正则表达式和非正则表达式配置的location进行了区分,并且把非正则表达式组织成了多叉树,把正则表达式组织成了list。对于前者,匹配的原则是最长匹配,而对于后者是采用优先匹配,也就是第一个匹配到的就是匹配结果。

匹配优先级总结: (location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (location /)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/687938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

福昕Foxit PDF远程代码执行漏洞CVE-2023-27363分析与复现

漏洞概述 福建福昕软件开发股份有限公司是一家国际化运营的PDF电子文档解决方案提供厂商&#xff0c;提供文档的生成、转换、显示、编辑、搜索、打印、存储、签章、表单、保护、安全分发管理等涵盖文档生命周期的产品技术与解决方案。其下产品Foxit PDF Reader和Foxit PDF Edit…

性能测试——App性能测试需要关注的指标

目录 一、Android客户端性能测试常见指标&#xff1a; 二、预期标准指定原则 三、测试方法及工具 一.从用户角度出发 二.站在管理员的角度考虑需要关注的性能点 三.站在开发(设计)人员角度去考虑 四.站在测试工程师角度考虑 总结&#xff1a; 一、Android客户端性能测试…

无功功率补偿及电容器的简单介绍 安科瑞 许敏

摘要&#xff1a;主要对无功功率的概念、电容器的补偿方式、补偿容量的计算等方面进行了阐述&#xff0c;在此基础上介绍了电容器运行的注意事项。 关键词&#xff1a;电力电容器&#xff1b;补偿方式 &#xff1b;运行 0 引言 笔者从进入吕合煤业从事电工工作的那天起&#…

Wav2Lip原理以及训练

原理 1: 音视频同步判别器 常规SyncNet&#xff1a; 功能&#xff1a;音频和嘴唇同步 实质&#xff1a;判断音频和唇形在某个共同参数空间下的相似性。 网络结构&#xff1a; 一种伪孪生网络结构&#xff0c;分别提取嘴形特征和音频特征&#xff0c;然后通过对比损失计算两者…

VS2017+OpenCV4.5.1 安装与配置,扩展模块opencv_contrib的安装与配置

文章目录 VS2017OpenCV4.5.1 安装与配置&#xff0c;扩展模块opencv_contrib的安装与配置1、OpenCV下载&#xff1a;&#xff08;1&#xff09;下载地址&#xff1a;https://opencv.org/releases/page&#xff08;2&#xff09;解压到指定文件夹&#xff1a; 2、配置环境&#…

如何进行可视化的数据过滤?Sugar BI 的过滤组件教你快速实现

Sugar BI 中支持了 10种过滤组件&#xff0c;这些过滤组件都是让用户在浏览报表或大屏的时候&#xff0c;能够交互式的对页面上的图表进行数据的过滤。所有过滤组件对图表的数据过滤设置都是一样的&#xff0c;如下&#xff1a; 例如页面中已有两个图表&#xff08;这两个图表…

人脑髓鞘化

髓鞘化 大纲&#xff1a;髓鞘化定义&#xff1b;髓鞘化能用来干嘛&#xff1b;髓鞘化现阶段存在的痛点&#xff1b;现有方法如何解决问题&#xff1b;我们方法的优势。 定义 髓鞘化是指髓鞘发展的过程&#xff0c;它使神经兴奋在沿神经纤维传导时速度加快&#xff0c;并保证…

开窗函数分享

开窗函数定义 开窗函数&#xff1a;用于为行定义一个窗口&#xff0c;它一组值进行操作&#xff0c;不需要使用group by子句对数据进行分组&#xff0c;能够在同一行中同时返回基础行的列和聚合列。 划重点!!! 开窗函数返回&#xff1a;基础行列、聚合列 下面通过例子看一下…

OJ# 376 机器翻译

题目描述 ​ 小李的电脑上安装了一个机器翻译软件&#xff0c;他经常用这个软件来翻译英语文章。 ​这个翻译软件的原理很简单&#xff0c;它只是从头到尾&#xff0c;依次将每个英文单词用对应的中文含义来替换。对于每个英文单词&#xff0c;软件会先在内存中查找这个单词的…

简单易用多git服务器ssh密钥配置管理

文章目录 前言一、什么是ssh-key二、配置步骤添加ssh-key配置多ssh-key 总结 前言 快速理解如何配置管理多个git服务器的ssh&#xff0c;当我们有多个git帐号时会涉及如何管理不同的remote使用不同的git账户登陆推送 当前repo的origin remote是github&#xff0c;我们在推送时…

EMMC基础知识总结

1、说明 1.0 整体架构 ‘ EMMC最简单的可理解为带有控制器的FLASH&#xff0c;具体结构如下&#xff1a; EMMC&#xff1a; Embedded multiMediaCard EMMC. EMMC内部&#xff1a; host interface 、 flash controller 、 flash memory 1.1 flash memory 结构 EMMC 中一般…

学习Vue3——watchEffect(高级侦听器)

立即运行一个函数&#xff0c;同时响应式地追踪其依赖&#xff0c;并在依赖更改时重新执行。 watchEffect有两个参数 第一个参数就是要运行的副作用函数 第二个参数是一个可选的选项&#xff0c;可以用来调整副作用的刷新时机或调试副作用的依赖 API—watchEffect 基本用法 …

电脑必备,推荐几款好用的程序软件,让你工作更加高效

在当今的信息化时代&#xff0c;电脑已成为我们日常生活中必不可少的工具。而在电脑上安装一些好用的程序软件&#xff0c;能够大大提高我们的工作效率和体验。但是市面上的软件五花八门&#xff0c;要如何选择呢&#xff1f;下面将为大家推荐几款值得使用的程序软件&#xff0…

告别脚本小子系列丨JAVA安全(8)——反序列化利用链(下)

0x01 前言 在前面的文章中介绍了基于CC链的反序列化利用方式&#xff0c;并且通过最终调用Runtime类的exec方法达到命令执行的效果。在CC链中还可以通过xalan来执行命令。 xalan是java操作xml的库&#xff0c;属于java内置的官方库之一&#xff0c;在CC链中主要用到的是com.sun…

论文研读|TNNLS 期刊近三年对话生成工作介绍(2篇)

前言&#xff1a;本篇博客记录TNNLS期刊近三年的对话生成相关工作中本人比较感兴趣的两篇工作。首先给大家分享一下论文精确查找的方式&#xff0c;然后对两篇工作的主要思想进行简要介绍。 目录 1. 论文精确查找方法2. 论文简介2.1 面向用户个性保持与回复多样性的两阶段对话生…

错误:No module named ‘osgeo’

from osgeo import gdal 报错&#xff1a;No module named ‘osgeo’ pip install gdal 会出错&#xff0c;也不知道什么原因。 解决方案&#xff1a; 下载whl,然后pip install .whl即可。 详细步骤如下&#xff1a; whl下载地址&#xff1a;https://www.lfd.uci.edu/~go…

基于java+servlet+mysql-图书商城

基于javaservletmysql-图书商城 一、系统介绍二、功能展示1.项目骨架2.首页3.图书详情4.我的订单5.我的购物车6、注册7、登录8、图书管理9、订单管理 四、其它1.其他系统实现五.获取源码 一、系统介绍 项目类型&#xff1a;Java web项目 项目名称&#xff1a;基于javaservlet…

浅谈企业能源监测管理系统的设计与应用

安科瑞 华楠 摘要: 针对企业目前能源监测现状, 结合企业信息化建设情况和发展需要, 介绍了能源监测管理信息系统, 提出了企业能源监测管理系统建设建议。 关键词:管理系统; 能源监测; 企业信息化 0 引言 节能降耗是缓解中国资源约束的根本出路, 也是提高企业自主创新能力的…

【机器学习】如何选择合适的假设函数

在前面的线性回归中&#xff0c;我们可以使用不同次数的多项式对数据集进行拟合&#xff0c;但是选择次数过低的多项式会导致欠拟合&#xff0c;选用次数过多的多项式会过拟合&#xff0c;那么如何选择合适的多项式呢&#xff1f;这就是本文需要解决的问题。 想要了解自己训练…

什么是α测试β测试和灰度测试?

吃软件测试这碗饭的&#xff0c;如果基础理论都不懂&#xff0c;谈何长久&#xff1f; 欢迎来学习本系列&#xff0c;基础理论比较枯燥&#xff0c;这也是为什么现在很少人掌握的主要原因。热饭尽量用浅显易懂 生动的例子 来帮助大家学习基础理论&#xff0c;所以请耐心看完此系…