Nginx Rewrite(重写)

==常用的Nginx正则表达式==
^:匹配输入字符串的起始位置
$:匹配输入字符串的结束位置
*:匹配前面的字符零次或多次。如“o1*" 能匹配"o”及“ol”、“oll”
+ :匹配前面的字符一次或多次。如“ol+"能匹配“ol"及“oll”、 “oll1”, 但不能匹配“o”
? :匹配前面的字符零次或次, 例如“do (es) ?"能匹配“do"或者“does", ”?”等效于"{0,1}”
.:匹配除"\n”之外的任何单个字符,若要匹配包括"\n”在内的任意字符,请使用诸如“[. \n]”之类的模式
\ :将后面接着的字符标记为一 个特殊字符或一 个原义字符或一 个向后引用。如“\n"匹配一 个换行符,而“\$”则匹配“$”
\d :匹配纯数字【0-9】  \s 空白符   \w 任意单词字符包括下划线 [A-Za-zA-Z0-9]
{n}:重复n次
{n,}:重复n次或更多次
{n,m} :重复n到m次
[]:定义匹配的字符范围
[c] :匹配单个字符c
[a-z] :匹配a-z小写字母的任意一-个
[a-zA-Z0-9] :匹配所有大小写字母或数字
():表达式的开始和结束位置
| :或运算符
从功能看rewrite和location 似乎有点像,都能实现跳转,主要区别在于rewrite是在同一域名内更改获取资源的路径,而
location是对一类路 径做控制访问或反向代理,还可以proxy_pass 到其他机器。


==rewrite 对访问的域名或者域名内的URL路径地址重写==

==location 对访问的路径做访问控制或者代理转发==

location 大致可以分为三类:

精准匹配: location = / {...} 一般匹配: location / {...} 正则匹配: location ~ / {...}

location常用的匹配规则:

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

location优先级:

首先精确匹配 = 其次前缀匹配 ^ ~ 其次是按文件中顺序的正则匹配 ~ 或 ~* 然后匹配不带任何修饰的前缀匹配 最后是交给 / 通用匹配

location示例说明:

(1) location = / {} =为精确匹配/,主机名后面不能带任何字符串,比如访问 / 和 / data,则/匹配,/data不匹配 再比如location = / abc, 则只匹配/ abc,/ abc/或/ abcd不匹配。若location / abc, 则即匹配/abc、/ abcd/ 同时也匹配/ abc /。

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

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

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

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

(6) location ~* . (gif l jpg l 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文件,如果和正则location ~ /images/abc/1.html 相比,正则优先级更高

优先级总结:

(location =完整路径) > (location ^~路径) > (location ~或者~*正则顺序) > (location 部分起始路径) > (location /)

location匹配

首先看优先级:精确> 前缀> 正则> 一般> 通用 优先级相同: 正则看上下顺序,上面的优先:

一般匹配看长度,最长匹配的优先 精确、前缀、正则、一般,都没有匹配到,最后再看通用匹配

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

第一个必选规则 直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。 可以是一一个静态首页,也可以直接转发给后端应用服务器 location = / { root html; index index . html index.htm;

第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用 location ^~ /static/ { root /webroot/static/ ;

}

location ~ * . (html Igif ljpg ljpeg Ipnglcssljslico)$ { root /webroot/res/ ;

}

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

location / { proxy_ pass http: I /tomcat server; }

1.验证规则的步骤一.PNG==验证规则的步骤一==

2.验证规则的步骤二.PNG==验证规则的步骤二==

3.验证规则的配置文件的配置.PNG==验证规则的配置文件的配置== 4.规则验证成功一.PNG==规则验证成功一==

5.规则验证成功二.PNG==规则验证成功二==

rewrite

rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。 比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。 rewrite只能放在server{},location{},if{}中,并且默认只能对域名后边的除去传递的参数外的字符串起作用, 例如http: L /www . kgc. com/ abc/bbs/ index . php?a=1&b=2只对/abc/bbs/ index . php重写。

Rewrite跳转场景

调整用户浏览的URL,看起来更规范,合乎开发及产 品人员的需求。 为了让搜索引擎搜录网站内容及用户体验更好,企业会 将动态URL地址伪装成静态地址提供服务。 网址换新域名后,让旧的访问跳转到新的域名上。例如 访问京东的360buy.com会跳转到jd.com。 服务端某些业务调整,比如根据特殊变量、目录、客户 端的信息进行URL调整等。

rewrite跳转实现: .

Nginx:通过ngx_ http_ rewrite_ module 模块支持URL重写、支持if条件判断,但不支持else 跳转:从一个location跳转到另一 个location,循环最多可以执行10次,超过后nginx将返回500错误 PCRE支持:perl兼容正则表达式的语法规则匹配 重写模块 set 指令:创建新的变量并设其值

Nginx跳转需求的实现方式

使用rewrite进行匹配跳转 使用if匹配全局变量后跳转 使用location匹配再跳转 rewrite放在server{}, if{}, location{} 段中 location只对域名后边的除去传递参数外的字符串起作用 对域名或参数字符串 使用if全局变量匹配 使用proxy_ pass反向代理

rewrite执行顺序如下:

(1) 执行server 块里面的rewrite指令。 (2) 执行location 匹配。 (3) 执行选定的location 中的rewrite指令。 语法格式: rewrite < regex > < replacement > [ flag ] ; regex:表示正则匹配规则。 replacement :表示跳转后的内容。 flag :表示rewrite 支持的flag 标记。

语法格式: rewrite < regex > < replacement > [ flag ] ;

regex : 表示正则匹配规则。 replacement : 表示跳转后的内容。 flag : 表示rewrite 支持的flag标记。

flag标记说明

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

rewrite示例:

(1)基于域名的跳转 现在公司旧域名www. kgc.com有业务需求变更,需要使用新域名www.benet. com代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变 vim /usr/local/ nginx/ conf/ nginx. conf server { listen 80; server_ name www. kgc. com; #域名修改 charset utf-8; access_ 1og /var/1og/ nginx/www . kgc . com-access. log; #日志修改 location / { #添加域名重定向 if ($host = 'www. kgc.com') { #$host为rewrite全局变量,代表请求主机头字段或主机名 rewrite ^/(.*)$ http:/ /www . benet。com/$1 permanent; #$1为正则匹配的内容,即“域名/”之后的字符串

​ } ​ root html ; ​ index index. html index. htm; ​ } }

echo "192.168.80.10 www. kgc. com www. benet.com" >> /etc/hosts systemctl restart nginx 浏览器输入模拟访问http: //www. kgc.com/ test/1.html (虽然这个请求内容是不存在的) 会跳转到www. benet.com/test/1.html,查看元素可以看到返回301,实现了永久重定向跳转,而且域名后的参数也正常跳转。

6.配置文件的修改.PNG==配置文件的修改==

7.创建一个目录然后写入相关内容.PNG==创建一个目录然后写入相关内容==

8.跳转前的地址.PNG==跳转前的地址==

9.这里是跳转成功,并且显示刚才写入的内容.PNG==这里是跳转成功,并且显示刚才写入的内容.==

10.这里返回的状态码是301.PNG==这里返回的状态码是301==

(2)基于客户端IP访问跳转 今天公司业务新版本E线,要求所有IP访问任何内容都显示一个固定维护页面, 只有公司IP : 192. 168.80.10访问正常。 vim /usr/ 1ocal/nginx/ conf/ nginx. conf server { listen 80; server_ name www. kgc. com; #域名修改 charset utf-8; access_ 1og /var/log/ nginx/www. kgc. com- access. log; #日志修改 #设置是否合法的IP标记 set $rewrite true; #设置变量$rewrite,变量值为boole值true #判断是否为合法IP if ($remote_ addr = "192.168.80.10") { #当客户端IP为192.168.80.10时,将变量值设为false,不进行重写 set $rewrite false;

}

#除了合法IP,其它都是非法IP,进行重写跳转维护页面 if ($rewrite = true) { #当变量值为true时,进行重写 rewrite (.+) /weihu . html; #将域名后边的路径重写成/we ihu. html,例如www. kgc. com/we ihu. html

}

location = /weihu.html { root /var/www/html; #网页返回/var/www/html/weihu. html的内容;

}

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

11.基于ip访问跳转配置文件修改地方.PNG==基于ip访问跳转配置文件修改地方==

12.进入该目录下面重新改写一个weihu的文件.PNG==进入该目录下面重新改写一个weihu的文件==

13.在本机上面用本机的ip地址进行访问发现能正常访问.PNG==在本机上面用本机的ip地址进行访问发现能正常访问==

14.换一台主机访问刚才的ip地址发现跳转到我们正在维护忙的界面.PNG==换一台主机访问刚才的ip地址发现跳转到我们正在维护忙的界面==

(3)基于旧域名到新域名的跳转 现在访问的是http:/ /bbs. kgc.com/post/,现在需要将这个域名下面的访问都跳转到http: //www. kgc. com/bbs/post/ vim /usr/ local/nginx/ conf/nginx. conf server { listen 80; server_ name bbs . kgc. com; #域名修改 charset utf-8; access_ 1og /var/ 1og/ nginx/www. kgc. com- access . log; #添加 location /post { rewrite (.+) http: I /www. kgc. com/bbs$1 pe rmanent; #这里的$1为位置变量,代表/post

}

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

}

mkdir -P /usr/1ocal/ nginx/html/bbs/post echo "this is 1.html" >> /usr/local/ nginx/html /bbs/ post/1.html echo "192.168.80.10 bbs. kgc. com" >> /etc/hosts

systemctl restart nginx 使用浏览器访问http: l/bbs。kgc. com/post/1。html跳转到http: //www.kgc .com/bbs/post/1. html 15.基于旧域名到新域名跳转后面加目录配置文件的修改.PNG==基于旧域名到新域名跳转后面加目录配置文件的修改==

(4)基于参数匹配的跳转 现在访问http: //www. kgc. com/100- (100 |200) -100. html跳转到http: //www. kgc. com页面。 vim /usr/ local/nginx/ conf/nginx. conf server { listen 80; server_ name www. kgc. com; #域名修改 charset utf-8; access_ log / var/1og/ nginx/ www . kgc . com- access.1og; if ($request_ uri ~ ^/100-(100|200)- (\d+) . html$) { rewrite (.+) http: //www. kgc. com permanent;

}

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

}

16.基于参数匹配跳转的配置文件修改.PNG==基于参数匹配跳转的配置文件修改==

17.实现了地址的转换.PNG==实现了地址的转换==

18.同样可以转换.PNG==同样可以转换==

(5)基于目录下所有php 结尾的文件跳转 要求访问http: L /www. kgc. com/upload/123.php跳转到首页。 vim /usr/ local/nginx/ conf/ nginx. conf server { listen 80; server_ name www. kgc. com; #域名修改 charset utf-8; access_ 1og /var/log/nginx/ www. kgc . com-access . log; location ~* /upload/ . *. php$ rewrite (.+) http: //www. kgc. com permanent;

}

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

​ }

}

systemctl restart nginx 浏览器访问http:/ /www . kgc . com/ upload/123. php跳转到http: L /www. kgc. com页面。

19.以.php结尾的跳转的配置文件修改.PNG==以.php结尾的跳转的配置文件修改==

20.以php结尾的文件自动跳转了.PNG==以php结尾的文件自动跳转了==