一、rewrite基础

  • 地址跳转

      地址重写		www.360buy.com——>jd.com
    
  • rewrite使用场景、实现原理

    1. 地址跳转:www.xuliangwei.com/class --> class.xuliangwei.com
    2. 协议跳转: http升级至https。 ( Rewrite方式来实现。 )
    3. URL静态化,将动态URL地址显示为静态URL地址的一种技术。
  • Rewrite URI重写配置语法

      set			设定变量
      if			条件判断
      return		返回数据
      rewrite
    

二、rewrite用例

需求1: 将用户请求url.oldxu.com.zh跳转至url.oldxu.com/zh
需求2: 将用户请求url.oldxu.com.jp跳转至url.oldxu.com/jp

[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
	listen 80;
	server_name url.oldxu.com.zh url.oldxu.com.jp;

	location / {
		#判断用户请求的域名是zh还是jp
		if ( $http_host ~* "zh" ) {
			set $language zh;
		}

		if ( $http_host ~* "jp" ) {
			set $language jp;
		}

		#配置rewrite跳转规则
		rewrite ^/$ http://url.oldxu.com/$language/ permanent;
	}
}

server {
	listen 80;
	server_name url.oldxu.com;
	root /opt;

	location / {
		index index.html;
	}
}
[root@web01 ~]# mkdir /opt/zh -p
[root@web01 ~]# mkdir /opt/jp -p
[root@web01 ~]# echo "zh.." > /opt/zh/index.html
[root@web01 ~]# echo "jp.." > /opt/jp/index.html
[root@web01 ~]# nginx -t
[root@web01 ~]# systemctl reload nginx

需求3: 过滤 Nginx 请求中包含 a1=3526 的http请求到 10.16.3.5 的 8080 端口处理。

server {
        listen 80;
        server_name url.oldxu.com;
        root /opt;

        location / {
                index index.html;

                #如果用户请求的uri中a1=3256,我们通过反向代理代理到10.16.3.5:8080端口
                if ( $request_uri ~* 'a1=3256' ) {
                        #proxy_pass http://10.16.3.5:8080;		#这个地址是不存在的
                        return 200 'ok....!';				#所以使用return来替代模拟 
                }
        }
}
测试的curl命令: curl -L -HHost:url.oldxu.com http://10.0.0.7?a1=3256
	-L 跟随跳转
	-H 指定Host头,具体要请求的域名是

三、return:主要用来返回数据|返回字符串|返回url地址。

  1. 如果用户使用 IE 访问 url.oldxu.com 则返回字符串 ( 请更换您的浏览器。 ) chrome
server {
	listen 80;
	server_name url.oldxu.com;
	root /opt;
	charset gbk,utf-8;
	location / {
		index index.html;
		default_type text/html;
		#判断用户使用的是否是 chrome浏览器,如果是则 返回一段话,如果不是则正常访问。
		if ( $http_user_agent ~* "chrome|MSIE" ) {
			return 200 'Please change Browser!!!';
		}
	}
}
  1. 如果使用IE访问,直接报错 500.
server {
	listen 80;
	server_name url.oldxu.com;
	root /opt;
	charset gbk,utf-8;
	location / {
		index index.html;
		default_type text/html;
		#判断用户使用的是否是 chrome浏览器,如果是则 返回一段话,如果不是则正常访问。
		if ( $http_user_agent ~* "chrome|MSIE" ) {
			return 500;
		}
	}
}
  1. 如果使用IE访问,直接跳转至浏览器下载页面。http://www.firefox.com.cn/
server {
	listen 80;
	server_name url.oldxu.com;
	root /opt;
	charset gbk,utf-8;
	location / {
		index index.html;
		default_type text/html;
		#判断用户使用的是否是 chrome浏览器,如果是则 返回一段话,如果不是则正常访问。
		if ( $http_user_agent ~* "chrome|MSIE" ) {
			return 302 http://www.firefox.com.cn;
		}
	}
}
  1. Rewrite Flag标记
    rewrite主要是用来重写URL、或者说是用来做URL地址跳转的

     关键字    正则表达式      替换成什么样子	标记
     Syntax:	rewrite   regex        replacement     	[flag];
     Default:	—
     Context:	server, location, if
     	last: 匹配成功,表示要停止继续匹配。
     请求的是1.HTML,最终的访问结果是a.html
     因为:在location{}内部,遇到last,本location{}内后续指令不在执行。
     匹配成功后,会重新像Server{}标签发起请求,从头到尾在匹配一遍规则,那个匹配则执行哪个。
     	break: 匹配成功,表示要停止继续匹配。
     请求的是1.HTML,最终的访问结果是2.html
     因为:在location {} 内部遇到了break,本location内以及后面的所有的location{}内的指令都不在执行。
    
  • break与last区别说明?
  1. 当rewrite规则遇到break后,本location{}与其他location{}的所有rewrite/return规则都不再执行。
  2. 当rewrite规则遇到last后,本location{}里后续rewrite/return规则不执行,但重写后的url再次从头开始执行所有规则,哪个匹配执行哪个。

[root@web01 ~]# cat   /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /code;

    location / {
        rewrite /1.html /2.html;
        rewrite /2.html /3.html last;
    }

    location /2.html {
        rewrite /2.html /a.html;
    }

    location /3.html {
        rewrite /3.html /b.html;
    }
}


http--https场景下:
	permanent:状态码301,永久跳转。	新跳转的网站有排名,旧网站排名会被清空。	1.html(排名会被清空)  2.html(有排名)
	redirect: 状态码302,临时跳转。	旧网站排名无影响,新网站没有排名。		1.html(不影响)	2.html(没有排名)

[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /code;

    location / {
        rewrite /1.html /2.html permanent;
    }
}

四、Rewrite相关案例

  • 需求1: 根据用户浏览器请求头中携带的语言调度到不同的页面。
    中国人: zh
    日本: jp
    url.oldxu.com [ 中国人看到的是 你好 | 国外人看到的是 hello。]
[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;

	#判断浏览器语言
	if ($http_accept_language ~* "zh|zh-cn" ) {
		set $language /zh;
	}

	if ($http_accept_language ~* "jp|ja" ) {
		set $language /jp;
	}

	#rewrite跳转
	rewrite  ^/$ $language;

	location / {
		index index.html;
	}
}
  • 需求2: 用户通过手机设备访问 url.oldxu.com,跳转至url.oldxu.com/m

    https://www.xhqb.com
    https://www.xhqb.com/m/

[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;

	#判断是否是手机
	if ($http_user_agent ~* 'android|iphone|ipad') {
		rewrite ^/$ /m last;
	}
	location / {
		index  index.html;
	}
}
  • 需求3: 用户通过手机设备访问 url.oldxu.com 跳转至 m.oldxu.com
    url.oldxu.com
    m.oldxu.com
[root@web01 ~]# cat  /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;

	#判断是否是手机
	if ($http_user_agent ~* 'android|iphone|ipad') {
		rewrite ^/$ http://m.oldxu.com redirect;
	}

	location / {
		index  index.html;
	}
}

server {
	listen 80;
	server_name m.oldxu.com;
	root  /opt/m;

	location / {
		index index.html;
	}
}
  • 需求4: 用户通过http协议请求,能自动跳转至https协议。
[root@web01 ~]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;

	#书写的方式很多
	#rewrite ^(.*)$ https://$server_name$1;
	return 302 $https://$server_name$request_uri;

}
  • 需求5: 网站在维护过程中,希望用户访问所有网站重定向至一个维护页面。 ( 在不变动nginx配置的情况下,进入维护页面。)
[root@web01 ~]# cat  /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;

	#维护状态
	rewrite ^(.*)$ /wh.html break;

	location / {
		index index.html;
	}
}
  • 需求6: 当服务器遇到 403 404 502 等错误时,自动转到临时维护的静态页。( 搜搜一些不存在的页面时,服务器会返回 孩子丢失的信息。 )
[root@web01 ~]# cat  /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;

	location / {
		index index.html;
	}
	error_page 403 404 502 = @tempdown;
	location @tempdown {
		rewrite ^(.*)$ /wh.html break;
	}
}
--------------https://404.life/   错误页面模板
[root@web01 error_page]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;

	location / {
		index index.html;
	}

	#碰到403 404 502 -->tempdown,tempdown内部重定向
	error_page 403 404 502 = @tempdown;
	location @tempdown {
		root /opt/error_page;
		rewrite ^(.*)$ /index.html break;
	}

}
  • 需求7: 公司网站在停机维护时,指定的IP能够正常访问,其他的IP跳转到维护页。 ( 学生 ) 10.0.0.1 可以访问,除此以外所有人都不能访问。
    方式一:
[root@web01 error_page]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;
	#初始一个变量为0
	set $ip 0;

	#判断来源IP是自己公司的服务器地址,则将ip变量设定为1
	if ($remote_addr ~ "10.0.0.1|10.0.0.2") {
		set $ip 1;
	}
	#判断如果ip变量判断是0,我们直接进入维护页面。
	if ($ip = 0) {
		rewrite ^(.*)$ /wh.html  break;
	}

	location / {
		index index.html;
	}
}

方式二:

[root@web01 error_page]# cat /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;


	location / {
		index index.html;
		allow 10.0.0.7/32;
		deny all;
	}

	location /error_page {
		root /opt;
	}


	error_page 403 = @temp;
	location @temp {
		return 302 'http://url.oldxu.com/error_page/index.html';
	}
}

需求8: 公司网站后台/admin,只允许公司的出口公网IP可以访问( 10.0.0.1 ),其他的IP访问全部返回500,或直接跳转至首页。

[root@web01 error_page]# cat   /etc/nginx/conf.d/url.oldxu.com.conf
server {
    listen 80;
    server_name url.oldxu.com;
    root /opt;

	location / {
		index index.html;
	}

	location /admin {
		index index.html;

	#设定一个初始变量,变量名为ip,变量的值为0
		set $ip 0;
	#判断来源的用户IP是多少,如果是10.0.0.7,则将变量名ip的值重置为1
		if ($remote_addr ~ "10.0.0.7") {
			set $ip 1;
		}
	#判断ip变量为0的,直接500拒绝。
		if ($ip = 0) {
			#return 500;
			return 302 'https://www.xuliangwei.com';
		}
	}
}