Nginx Rewrite
1.什么是Rewrite
Rewrite主要用于URL地址重写,以及URL地址跳转
就是将用户请求的web服务器URL地址重新改为其他URL地址的过程
例如:
域名 | 重写后的域名 |
---|---|
www.z.cn | www.amazon.cn |
www.g.cn | www.google.cn |
www.360buy.com | www.jd.com |
rewrite 表达式可以应用在server 、location、if标签下
语法:rewrite -----正则 ----- 替代内容 ----- flag标记
flag标记
last :本条规则匹配完后,继续向下匹配新的location URI规则
break :本条规则匹配完后即终止,不再向下匹配任何的规则
redirect:返回302临时重定向,地址栏显示跳转后的地址
permanent:返回301永久重定向,地址栏显示跳转后的地址
2.Rewrite使用场景
1.地址跳转:用户请求www.wang.com/test这个URL的时候,将其定向至新的地址test.wang.com
2.协议跳转:将客户端发起的http的请求协议重新跳转至https协议
3.URL静态化:将动态的URL地址显示为静态的URL的一种技术,能提高搜索引擎抓取率,减少动态URL对外暴露过多参数
3.Nginx Rewrite重写过程
4.Rewrite重写的相关模块
if --- 负责语句中的判断
set --- 设置变量
return --- 返回URL或者返回值
rewrite --- 重定向URL
1.if模块
例: 过滤 请求到rewrite.test.com的请求中包含 test 的http请求到 192.168.51.163 的 8080端⼝处理。
1.域名为rewrite.test.com的web节点配置:
vim /etc/nginx/conf.d/rewrite.test.com.conf
server {
listen 80;
server_name rewrite.test.com;
root /html;
location / {
index index.html;
if ($request_uri ~ 'test') { #判断请求的URI中如果包含test字样就将请求调度到192.168.51.163的8080端口处理
proxy_pass http://192.168.51.163:8080; #将请求调度到192.168.51.163的8080端口处理
}
}
}
--------------------------------------
重载nginx
nginx -t
systemctl reload nginx
--------------------------------------
记得测试时候在本地做域名解析
...
192.168.xx.xxx rewrite.test.com
...
2.在192.168.51.163节点上配置
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 8080;
root /html;
location / {
index index.html
}
}
---------------------------------------------
准备配置文件
echo ‘this is rewrite test....ip :192.168.51.163........................’ > /html/test.html
---------------------------------------------
重载nginx
nginx -t
systemctl reload nginx
3.测试结果:
当访问rewrite.test.com/test.html时候,URI中包含test,就会将请求跳转到192.168.51.163:8080进行处理
访问仅包含test 的URI,虽然会报错…
但是请求还是会调度到192.168.51.163:8080端口处理
2.set模块
set 变量名称 变量的值
例:将用户请求xx.test.com跳转到test.com/xx,将用户请求yy.test.com跳转到test.com/yy
1.配置web节点
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name test.com;
root /html;
location / {
index index.html;
}
}
server {
listen 80;
server_name xx.test.com yy.test.com;
if ( $http_host ~* "xx" ) { #如果用户请求的域名中包含xx,就设置一个变量$language,变量值为xx
set $language xx;
}
if ( $http_host ~* "yy" ) { #如果用户请求的域名中包含yy,就设置一个变量$language,变量值为yy
set $language yy;
}
rewrite ^/$ http://test.com/$language; #跳转到test.com/$language的URL,根据不同的变量值跳转到不同的URL
}
2.准备页面文件
echo 'xx test' > /html/xx/index.html
echo 'yy test' > /html/yy/index.html
3.配置DNS解析
...
192.168.xx.xxx test.com xx.test.com yy.test.com
4.查看测试结果
访问xx.test.com会跳转到test.com/xx路径下
访问yy.test.com会跳转到test.com/yy路径下
3.return模块
return ( 返回数据 | 字符串 | URL地址 )
3.1返回字符串
例:如果使⽤火狐浏览器访问,则提示 “ 更换浏览器访问”
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name test.com;
charset utf-8; #设定访问的默认首页地址,解决中文乱码问题
default_type text/html; #默认文件类型
if ( $http_user_agent ~* "firefox" ) { #判断用户使用的是否为火狐浏览器
return 200 '"请更换浏览器后访问";
}
}
用火狐浏览器打不开,用其他的浏览器可以打开
3.2返回数据
例:如果使⽤火狐浏览器访问,则返回500报错
server {
listen 80;
server_name test.com;
root /html;
if ( $http_user_agent ~* "firefox") {
return 500;
}
3.3返回URL
例:使用火狐浏览器访问test.com的时候,返回一个URL,跳转到这个URL
server {
listen 80;
server_name test.com;
root /html;
if ( $http_user_agent ~* "firefox") {
return https://www.jd.com;
}
例:当⽤户通过⼿机设备访问 www.test.com,跳转⾄www.test.com/mobile
思路:先判断他是⼿机还是pc
• pc:正常访问
• 手机:rewrite跳转
server {
listen 80;
server_name www.test.com;
root /html;
charset utf-8;
default_type text/html;
if ( $http_user_agent ~* "android|iphone|ipad") { #判断如果用户使用的是这些移动端,就跳转到移动端的页面
rewrite ^/$ http://www.test.com/mobile;
}
location / {
index index.html;
}
}
当用户使用手机访问www.test.com的时候,打开的是手机的页面
当用户使用电脑访问www.test.com时候,访问的是PC的页面
4.rewrite模块
例1:当服务器遇到 403 404 502 等错误时,⾃动转到临时维护的静态⻚
1.准备静态页面
vim /html/maintain/index.html
<!DOCTYPE html> #腾讯公益404页面
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script
type="text/javascript"
src="https://volunteer.cdn-go.cn/404/latest/404.js">
</script>
</head>
<body>
<div class="footer">
</div>
</body>
</html>
2.编辑nginx配置文件
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name www.test.com;
root /html;
location / {
index index.html;
}
error_page 403 404 500 502 = @temp; #当碰到了403 404 500 502 等错误,都重定向到 @temp上
location @temp { #location @ 只⽤于接收内部跳转,(不⽤于常规匹配请求)
rewrite ^(.*)$ http://www.test.com/maintain;
}
}
3.重载nginx
nginx -t
systemctl reload nginx
4.查看测试结果
访问www.test.com是正常访问的
随意访问一个不存在的页面就会报错,就可以跳转到预先设定的静态页面
www.test.com/bdjcbajhcbj
例2:公司⽹站在停机维护时,指定的IP能够正常访问,其他的IP跳转到维护⻚面
1.编辑nginx配置文件
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name rewrite.test.com;
root /html;
location / {
index index.html;
}
}
server {
listen 80;
server_name www.test.com;
root /html;
set $ip 0; #初始化⼀个ip变量为0
if ( $remote_addr ~ "192.168.51.164|192.168.51.165") { #如果来源IP为192.168.51.164|192.168.51.165 则设定变量为1
set $ip 1;
}
if ($ip = 0) { #如果ip变量为0,则进⼊维护页面
rewrite ^(.*)$ http://rewrite.test.com/maintain;
}
location / {
index index.html;
}
}
3.重载nginx
nginx -t
systemctl reload nginx
2.查看测试结果
来源IP为192.168.51.164、192.168.51.165 的主机都可以正常访问www.test.com
但是此外的其他来源IP就只能访问维护页面了
5.Rewrite 的flag标记
flag标记
last :本条规则匹配完后,继续向下匹配新的location URI规则
break :本条规则匹配完后即终止,不再向下匹配任何的规则
redirect:返回302临时重定向,地址栏显示跳转后的地址
permanent:返回301永久重定向,地址栏显示跳转后的地址
1.last
例:当请求/1.html时,最终会访问到/a.html
1.准备文件
创建1.html 2.html 3.html a.html b.html这5个测试文件
touch /html/{1,2,3,a,b}.html
给2.html与a.html写入内容
echo 'this is 2.html' >/html/2.html
echo 'this is a.html' >/html/a.html
2.编辑nginx配置文件
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name www.test.com;
root /html;
charset utf-8;
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;
}
}
3.重载nginx
nginx -t
systemctl reload nginx
4.查看结果
请求www.test.com/1.html时最终访问的是a.html页面内容
有last的执行流程:
2.break
例1:同样的配置文件,将last改为break后,同样访问1.html最终只会访问到2.html
编辑nginx配置文件
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name www.test.com;
root /html;
charset utf-8;
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;
}
}
3.重载nginx
nginx -t
systemctl reload nginx
4.查看测试结果
访问1.html,最终会访问到2.html的页面
有break的执行流程:
例2:⽹站在维护过程中,希望⽤户访问所有⽹站重定向⾄⼀个维护⻚⾯
1.准备文件
mkdir -p /html/maintain
---------------------------------------------------
vim /html/index.html
<meta charset="utf-8">
<h1>www.test.com网站正常运行中。。。</h1>
----------------------------------------------------
vim /html/maintain/index.html
<meta charset="utf-8">
<h1>www.test.com网站升级维护中。。。</h1>
2.编辑nginx配置文件
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name www.test.com;
root /html;
rewrite ^/$ http://www.test.com/maintain break; #这里遇到break,后面的指令将不再执行
# 将rewrite规则注释掉后,就可以恢复正常访问
location / {
index index.html;
}
}
3.重载nginx
nginx -t
systemctl reload nginx
4.查看测试结果
访问www.test.com时,会跳转到维护页面
将rewrite规则注释掉后,就可以恢复正常访问
last与break的区别
当rewrite规则遇到last后,本location{}里后续的指令不再执行,但是重写后的URL会从所在server{}从头开始匹配一遍所有规则,匹配到哪个规则就执行哪个规则。
当rewrite规则遇到break后,本location{}剩余的指令,以及后面其他location{}的所有指令都不再执行。
3.redirect
例:当通过手机访问www.test.com的时候,会自动跳转到moible.test.com页面
1.准备文件
mkdir -p /html/moible
echo 'the version is pc <br> www.test.com' >/html/index.html
echo 'the version is moible <br> www.test.com' >/html/moible/index.html
2.编辑nginx配置文件
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name www.test.com;
root /html;
if ($http_user_agent ~* "android|iphone") {
rewrite ^/$ http://mobile.test.com redirect; #临时跳转
}
location / {
index index.html;
}
}
server {
listen 80;
server_name mobile.test.com;
root /html/mobile;
location / {
index index.html;
}
}
3.重载nginx
nginx -t
systemctl reload nginx
4.查看测试结果
用手机访问www.test.com时,URL会跳转到moible.test.com
查看状态码,显示302临时跳转
4.permanent
例:把临时跳转参数redirect,改为永久跳转参数permanent,看看会有什么不同
vim /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name www.test.com;
root /html;
if ($http_user_agent ~* "android|iphone") {
rewrite ^/$ http://mobile.test.com permanent; #永久跳转
}
location / {
index index.html;
}
}
server {
listen 80;
server_name mobile.test.com;
root /html/mobile;
location / {
index index.html;
}
}
3.重载nginx
nginx -t
systemctl reload nginx
使用手机访问过一次www.test.com后,在pc模式下访问www.test.com,最终还是跳转到moible.test.com页面
redirect与permanent的区别
都是跳转,他们的区别在哪
这里的影响指的是对网站优化的影响