Rewrite重写
# Rewrite URL重写概述
# 什么是rewrite
Rewrite主要实现url地址重写,以及url地址跳转。
就是将用户请求web服务器的URL地址重新修改为其他URL地址的过程。
# Rewrite使用场景
- 地址跳转,用户访问www.birenchong.cn/class这个URL时,将其定向至一个新的域名class.birenchong.cn;
- 协议跳转,将用户通过http的请求协议重新跳转至https协议(实现https主要手段)。
- URL静态化,将动态URL地址显示为静态URL的一种技术,能提高搜索引擎抓取,并且能减少动态URL对外暴露过多的参数。PS: Rewrite会轻微增加服务器负担。
# Rewrite重写原理
# Rewrite重写相关模块
set 设置变量
if 负责语句中的判断
return 返回返回值或URL
rewrite 重定向URL
# Rewrite URL重写模块
# if指令
Syntax : if (condition) { ... }
Default: —
Context: server,location
# ~ 模糊匹配
# ~* 不区分大小写匹配
# !~ 不匹配
# = 精确匹配
2
3
4
5
6
7
需求1:过滤Nginx请求中包含a1=3526的http请求到10.16.3.5的8080端口处理。
server {
listen 80;
server_name url.birenchong.cn;
default_type application/json;
root /code;
location / {
index index.html;
if ($request_uri ~* 'a1=\d{4}') {
proxy_pass http://10.16.3.5:8080;
}
}
}
#\d表示数字,{4,8}表示数字出现的次数是4到8次,如gid=12345678就符合该条件。
if ($request_uri ~* 'good=\d{4,8}/') {
动作;
}
#测试
#curl -L url.birenchong.cn/?id=123456
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# set指令
Syntax : set $variable value;
Default: —
Context: server,location,if
2
3
需求2: 将用户请求url.birenchong.cn.zh跳转至url.birenchong.cn/zh 需求3: 将用户请求url.birenchong.cn.jp跳转至url.birenchong.cn/jp
server {
listen 80;
server_name url.birenchong.cn.zh url.birenchong.cn.jp;
location / {
if ($http_host ~* "zh") {
set $language zh;
}
if ($http_host ~* "jp") {
set $language jp;
}
rewrite ^/$ http://url.birenchong.cn/$language/permanent;
}
}
server {
listen 80;
server_name url.birenchong.cn;
location / {
root /code;
index index.html;
}
}
#准备代码
[root@web01 ~]# mkdir /code/jp /code/zh
[root@web01 ~]# echo "zh" > /code/zh/index.html
[root@web01 ~]# echo "jp" > /code/jp/index.html
[root@web01 ~]# systemctl restart nginx
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# return指令
1.return数据返回语法
Syntax : return code;
return code [text];
return URL;
Default: -
Context: server,location,if
2
3
4
5
需求1:如果用户使用IE浏览器访问url.birenchong.cn,则返回一段字符串。
server {
listen 80;
server_name url.birenchong.cn;
root /code;
default_type text/html;
charset utf-8;
location / {
index index.html;
if ($http_user_agent ~* "MSIE|firefox") {
return 200 "请更换浏览器";
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
需求2:如果用户使用IE浏览器访问url.birenchong.cn,则返回500错误。
server {
listen 80;
server_name url.birenchong.cn;
root /code;
default_type text/html;
charset utf-8;
location / {
index index.html;
if ($http_user_agent ~* "MSIE|firefox”) {
return 500;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
需求3:如果用户使用E浏览器访问url.birenchong.cn,则直接跳转至百度。
server{
listen 80;
server_name url.birenchong.cn;
root /code;
default_type text/html;
charset utf-8;
location / {
index index.html;
if ($http_user_agent ~* "MSIE|firefox") {
return 302 https://www.baidu.com;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# Rewrite重写语法
rewrite主要是用来重写URL或者跳转URL的指令。
#rewrite表达式可以应用在server,location,if标签下
# 关键字 正则 替代内容 flag标记
Syntax : rewrite regex replacement [flag];
Default: --
Context: server,location,if
#flag
last #本条规则匹配完成后,继续向下匹配新的location URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,地址栏会显示跳转后的地址
permanent #返回301永久重定向,地址栏会显示跳转后的地址
2
3
4
5
6
7
8
9
10
11
# break与last区别
1.编写rewrite相关代码示例:
server {
listen 80;
server_name url.birenchong.cn;
root /code;
location / {
rewrite /1.html /2.html;
rewrite /2.html /3.html;
}
location /2.html {
rewrite /2.html /a.html;
}
location /3.html{
rewrite /3.html /b.html;
}
}
#准备对应代码
[root@web01 ~]# echo "1.html" >/code/1.html
[root@web01 ~]# echo "2.html" >/code/2.html
[root@web01 ~]# echo "3.html" >/code/3.html
[root@web01 ~]# echo "a.html" >/code/a.html
[root@web01 ~]# echo "b.html" >/code/b.html
#测试结果:当请求/1.html,最终将会访问/b.html
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2.为该代码增加break
server {
listen 80;
server_name url.birenchong.cn;
root /code;
location /{
rewrite /1.html /2.html break;
rewrite /2.html /3.html;
}
location /2.html{
rewrite /2.html /a.html;
}
location /3.html ;
rewrite /3.html /b.html;
}
}
#测试结果:当请求/1.html,最终会访问/2.html
#因为︰在location{}内部,遇到break,本location{}内以及后面的所有location{}内的所有指令都不再执行。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
3.为该代码增加last
server {
listen 80;
server_name url.birenchong.cn;
root /code;
location / {
rewrite /1.html /2.html last;
rewrite /2.html /3.html;
}
location /2.html {
rewrite /2.html /a.html;
}
location /3.html {
rewrite /3.html /b.html;
}
}
#测试结果:当请求/1.html,最终会访问/a.html
#因为:在location{}内部,遇到last,本location[}内后续指令不再执行
#而重写后的url会对所在的server{...}标签重新发起请求,从头到尾匹配一遍规则,那个匹配则执行哪个。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
4.break与last区别说明 当rewrite规则遇到break后,本location{}与其他location{}的所有rewrite/return规则都不再执行。当rewrite规则遇到last后,本location{}里后续rewrite/return规则不执行,但重写后的url再次从头开始执行所有规则,哪个匹配执行哪个。
# redirect与permanent区别
1.redirect与permanent区别对比示例
server {
listen 80;
server_name url.birenchong.cn;
root /code;
location / {
rewrite /1.html /2.html redirect;
}
}
2
3
4
5
6
7
8
9
2.通过浏览器访问测试,会发现无论是permanent、还是redirect会进行跳转。
3.那么redirect和permanent都是跳转,那redirect和permanent区别在哪呢?
Flag | 跳转 | 状态码 | 排名情况 |
---|---|---|---|
redirect | 临时跳转 | 302 | 对旧网站无影响,新网站会有排名 |
permanent | 永久跳转 | 301 | 新跳转网站有排名,旧网站排名会被清空 |
# Rewrite生产案例实践
需求1:根据用户浏览器请求头中携带的语言调度到不同的页面
server {
listen 80;
server_name url.birenchong.cn;
root /code;
if ($http_accept_language ~* "zh-CN|zh") {
set $language /zh;
}
if ($http_accept_language ~* "en") {
set $language /en;
}
rewrite ^/$ $language; #根据语言跳转对应的站点
location / {
index index.html;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
需求2:用户通过手机设备访问url.birenchong.cn,跳转至url.birenchong.cn/m
server {
listen 80;
server_name url.birenchong.cn;
root /code;
if ($http_user_agent ~* "android|iphone|ipad") {
rewrite ^/$ /m;
}
}
2
3
4
5
6
7
8
9
需求3:用户通过手机设备访问url.birenchong.cn跳转至m.birenchong.cn
server {
listen 80;
server_name url.birenchong.cn;
root /code;
if ($http_user_agent ~* "android|iphone|ipad") {
rewrite ^/$ http://m.birenchong.cn;
}
}
server {
listen 80;
server_name m.birenchong.cn;
root /data/m;
location / {
index index.html;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
需求4:用户通过http协议请求,能自动跳转至https协议
server {
listen 80;
server_name url.birenchong.cn;
return 302 https://$server_name$request_uri;
# rewrite ^(.*)$ https://$server_name$1 redirect;
}
server {
listen 443;
server_name url.birenchong.cn;
ssl on;
}
2
3
4
5
6
7
8
9
10
11
12
需求5:网站在维护过程中,希望用户访问所有网站重定向至一个维护页面
server {
listen 80;
server_name url.birenchong.cn;
root /code;
#配置示例
rewrite ^(.*)$ /wh.html break;
location / {
index index.html;
}
}
2
3
4
5
6
7
8
9
10
11
需求6:当服务器遇到403 403 502等错误时,自动转到临时维护的静态页 错误页面模板 (opens new window)
server {
listen 80;
server_name url.birenchong.cn;
root /code;
location / {
index index.html;
}
#配置示例
error_page 404 403 502 = @tempdown;
location @tempdown {
rewrite ^(.*)$ /wh.html break;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
需求7:公司网站在停机维护时,指定的IP能够正常访问,其他的IP跳转到维护页
server {
listen 80;
server_name url.birenchong.cn;
root /code;
#1.在server层下设定ip变量值为0
set $ip 0;
#2.如果来源IP是10.0.0.101 102则设定变量为ip变量为1。
if ($remote_addr = "10.0.0.101|10.0.0.102") {
set $ip 1;
}
#3.如果来源IP不是10.0.0.101 102、则跳转至/code/wh.html这个页面,否则不做任何处理
if ($ip = 0) {
rewrite ^(.*)$/wh.html break;
}
#-->如果想针对某个location进行操作,则将如上配置写入location中即可
location /{
index index.html;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
需求8:公司网站后台/admin,只允许公司的出口公网P可以访问,其他的IP访问全部返回500,或直接跳转至首页
#限制访问来源IP
location /admin {
set $ip 0;
if ($remote_addr = "61.149.186.152|139.226.172.254") {
set $ip 1;
}
if ($ip = 0){
return 500;
#rewrite /(.*)$ https://url.birenchong.cn redirect;
}
}
2
3
4
5
6
7
8
9
10
11