Nginx-rewrite
主要实现url地址重写,url地址跳转
rewrite应用场景
Rewrite重写模块
if条件判断指令
需求:匹配nginx请求中包含id=2356的,然后代理到10.16.3.5的8080端口
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_if.conf
server {
listen 80;
server_name url.zjh.net;
root /code;
location / {
index index.html;
if ($request_uri ~ 'id=2356') {
proxy_pass http://10.16.3.5:8080;
}
}
}
set设定变量
需求:通过user_agent(header)拦截压测测试工具
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_set.conf
server {
listen 80;
server_name url.zjh.net;
root /code;
location / {
index index.html;
if ($http_user_agent ~* "curl|firefox") {
set $deny_user_agent 1;
}
if ($deny_user_agent = 1) {
return 403;
}
}
}
return返回数据指令
location / {
default_type text/html;
if (\$http_user_agent ~* "iphone|android|ipad") {
proxy_pass http://phone;
}
if ($http_user_agent ~* "MSIE|Trident") {
#return 403; (返回403状态码)
return 200 'Please Change Browser'; (返回请更换浏览器)
#return 302 'https://www.firefox.com.cn/download/thanks/'; (自动跳转下载其他浏览器)
}
proxy_pass http://pc;
include proxy_params;
}
Rewrite重写Flag
#flag
last #本条规则匹配完成后,继续向下匹配新的location URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,地址栏会显示跳转后的地址
permanent #返回301永久重定向,地址栏会显示跳转后的地址
break(通常用于停机维护)
[root@web01]# cat url.oldxu.net.conf
server {
listen 80;
server_name url.oldxu.net;
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{}内的所有指令都不再执行。
last(通常用于将动态请求改为静态地址)
[root@web01]# cat url.oldxu.net.conf
server {
listen 80;
server_name url.oldxu.net;
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{}标签重新发起请求,从头到尾匹配一遍规则,哪个匹配则执行哪个
附加:break与last的区别
当 rewrite 规则遇到 break 后,本 location{} 与其他 location{} 的所有规则都不执行。
当 rewrite 规则遇到 last 后,本 location{} 里后续规则不执行,但重写后的url 会再次从头开始匹配所有 Location,哪个匹配执行哪个。
redirect(302临时跳转,对旧网站无影响,新网站会继承排名)
[root@web01]# cat url.oldxu.net.conf
server {
listen 80;
server_name url.oldxu.net;
root /code;
location / {
rewrite /1.html /2.html redirect;
rewrite /2.html /3.html;
}
}
permanent(301永久跳转,新网站继承排名,旧网站排名会清空)
[root@web01]# cat url.oldxu.net.conf
server {
listen 80;
server_name url.oldxu.net;
root /code;
location / {
rewrite /1.html /2.html permanent;
rewrite /2.html /3.html;
}
}
Rewrite跳转实例
1、根据用户浏览器请求头中携带的语言调度到不同的页面
mkdir /code4
mkdir /code4/zh
mkdir /code4/en
echo "zh..." > /code4/zh/index.html
echo "en..." > /code4/en/index.html
[root@web01 ~]# vim /etc/nginx/conf.d/url.zjh.net_language.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
location / {
if ($http_accept_language ~* "zh|zh-cn") {
set $language zh;
}
if ($http_accept_language ~* "en|jp") {
set $language en;
}
rewrite ^/$ /$language;
}
}
2、根据用户不同的设备调度到不同的页面中
[root@web01 ~]# mkdir /code4/m
[root@web01 ~]# echo "phone..." > /code4/m/index.html
[root@web01 ~]# echo "www..." > /code4/index.html
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_agent.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
location / {
if ($http_user_agent ~* "android|iphone|ipad") {
rewrite ^/$ /m redirect;
}
}
}
3、根据用户不同的设备调度到不同的域名中
[root@web02 ~]# cat /etc/nginx/conf.d/m.zjh.net.conf
server {
listen 80;
server_name m.zjh.net;
root /code4;
location / {
index index.html;
}
}
[root@web02 ~]# echo "web02..." > /code4/index.html
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_mobile.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
location / {
if ($http_user_agent ~* "android|iphone|ipad") {
rewrite ^/$ http://m.zjh.net redirect;
}
}
}
4、用户通过http协议请求时自动跳转到https协议访问
server {
listen 80;
server_name url.zjh.net;
root /code4;
# 可使用的变量名
# $http_host
# $server_name
# $host
rewrite ^(.*)$ https://$http_host$1 redirect;
# return 302 https://$http_host$request_uri;(第二种写法)
}
server {
listen 443;
server_name url.zjh.net;
}
5、网站维护过程中,用户访问网站时自动重定向到一个维护页面
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_wh.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
charset utf8,gbk;
#维护页面开关,需要启用时把注释删掉启用
#rewrite ^(.*)$ /wh.html break;
location / {
index index.html;
}
}
[root@web01 ~]# echo "维护中..." > /code4/wh.html
6、当网站遇到403 404 502时,自动跳转到临时维护的静态页面
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_404.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
charset utf8,gbk;
location / {
index index.html;
}
error_page 404 403 502 500 503 504 @error_wh;
location @error_wh {
rewrite ^(.*)$ /wh.html break;
}
}
[root@web01 ~]# echo "维护中..." > /code4/wh.html
7、公司在停机维护时,指定ip地址能正常访问,其他ip地址跳转到维护页面
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_ip.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
charset utf8,gbk;
location / {
index index.html;
#将IP变量设定为0
set $ip 0;
#将指定机器的IP变量设定为1,则可以正常访问
if ($remote_addr ~ "10.0.0.1|10.0.0.2") {
set $ip 1;
}
#其余非指定IP的机器将IP变量设定为0,跳转到维护页面
if ($ip = 0) {
rewrite ^(.*)$ /wh.html break;
}
}
}
8、公司网站后台/admin只允许公司的公网IP访问,其余IP全部返回状态值500,或跳转会首页
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_admin.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
charset utf8,gbk;
location / {
index index.html;
set $ip 0;
if ($remote_addr ~ "10.0.0.1|10.0.0.2") {
set $ip 1;
}
if ($ip = 0) {
rewrite ^(.*)$ /wh.html break;
}
}
location /admin {
limit_rate 100k;
#设定IP变量为0
set $ip 0;
#设定公司的公网地址为1,允许访问admin目录
if ($remote_addr ~ 10.0.0.1) {
set $ip 1;
}
#其余IP变量设定为0,返回状态码404,或返回主页
if ($ip = 0) {
#return 404;
return 302 http://$http_host;
}
}
}
9、当用户请求url.zjh.net/bbb时,实际是在请求http://demo:27610/test/bbb(最后一级域,放在uri的第一个路径,实际请求的uri,写到第二级路径)
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_domain.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
charset utf8,gbk;
location / {
index index.html;
if ($http_host ~* (.*)\.(.*)\.(.*)) {
set $domain $1;
}
rewrite ^(.*)$ http://demo:27610/$domain$request_uri redirect;
}
}
10、现有两台服务器,当用户访问http://url.oldxu.net/index.php?r=survey/index/sid/613192/lang/zh-Hans,若访问资源为/index.php?r=survey...时,跳转到另一台服务器http://sur.oldxu.net/index.php?r=survey/index/sid/613192/lang/zh-Hans
请求的域名:http://url.oldxu.net/index.php?r=survey/index/sid/613192/lang/zh-Hans
替换后域名:http://sur.oldxu.net/index.php?r=survey/index/sid/613192/lang/zh-Hans
(只替换域名,后面的uri部分原封不动)
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_uri.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
charset utf8,gbk;
location / {
index index.html;
if ($args ~* "r=survey") { #args表示uri中问号后面的参数
rewrite ^(.*)$ http://sur.zjh.net/$request_uri? redirect;
#问号表示丢弃原始请求的uri参数,如果没添加问号会导致"Location: http://sur.zjh.net//index.php?r=survey/index/sid/613192/lang/zh-Hans r=survey/index/sid/613192/lang/zh-Hans(uri问号部分参数重复)"
}
}
}
11、当用户访问http://url.zjh.net/?id=2时,替换为http://url.zjh.net/id/2.html
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_id.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
charset utf8,gbk;
location / {
index index.html;
if ($args ~ "id") {
set $OK 1;
}
if ($args ~ (.*)=(.*)) {
set $id $1;
set $num $2;
}
if ($OK = 1) {
rewrite ^(.*)$ http://http://$http_host/$id/$num.html? last;
}
}
}
12、禁止搜索引擎爬取网站(通过user_agent防止搜索引擎的爬取)
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_agent.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
charset utf8,gbk;
location / {
index index.html;
if ($http_user_agent ~* "YisouSpider|baiduSpider|YoudaoBot") {
return 403;
}
}
}
[root@web02 ~]# curl -L -I -A "yisouspider" -HHost:url.zjh.net http://10.0.0.7
HTTP/1.1 403 Forbidden
Server: nginx/1.26.1
Date: Wed, 07 May 2025 03:07:44 GMT
Content-Type: text/html; charset=utf8,gbk
Content-Length: 153
Connection: keep-alive
13、禁止站点资源被盗用
[root@web01 ~]# cat /etc/nginx/conf.d/url.zjh.net_tou.conf
server {
listen 80;
server_name url.zjh.net;
root /code4;
charset utf8,gbk;
location / {
index index.html;
}
location ~ .*\.(jpg|png|jpeg|gif)$ {
valid_referers none blocked *.zjh.net; (允许通过的域名白名单)
if ($invalid_referer) {
# return 403;
rewrite ^(.*)$ /error.jpg break; (被盗图时返回自定义的图片)
}
}
}