nginx 地址重写--rewrite

本文详细解释了Nginx中的Rewrite功能,包括URL重写原理、相关指令如if、rewrite和set的作用,以及通过实例展示如何在Nginx配置中使用这些指令进行地址重定向、路径处理和状态码控制。
摘要由CSDN通过智能技术生成

1、什么是Rewrite

Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程。
  • URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。理论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所以,UrlRewrite可以让我们网站的网页更容易被搜索引擎所收录。

  • 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。

  • 实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com的80端口时,将其跳转到443端口。

2、Rewrite 相关指令

  • Nginx Rewrite 相关指令有 if 、rewrite、set、return

2.1、if 语句
  • 应用环境:server,location

语法: 

if (condition) { … }
if 可以支持如下条件判断匹配符号
~                   正则匹配 (区分大小写)
~*                  正则匹配 (不区分大小写)
!~                  正则不匹配 (区分大小写)
!~*                 正则不匹配  (不区分大小写)
-f 和!-f             用来判断是否存在文件
-d 和!-d             用来判断是否存在目录
-e 和!-e             用来判断是否存在文件或目录
-x 和!-x             用来判断文件是否可执行
在匹配过程中可以引用一些Nginx的全局变量----nginx中配置文件里面的参数都只能用“_”来连接和书写,不能用"-"连接,会报错。

$args               请求中的参数;
$document_root      针对当前请求的根路径设置值;
$host               请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$limit_rate         对连接速率的限制;
$request_method     请求的方法,比如"GET"、"POST"等;
$remote_addr        客户端地址;
$remote_port        客户端端口号;
$remote_user        客户端用户名,认证用;
$request_filename   当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images/a.jpg)
$request_uri        当前请求的文件路径名(不带网站的主目录/images/a.jpg)
$query_string       与$args相同;
$scheme             用的协议,比如http或者是https
$server_protocol    请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr        服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name        请求到达的服务器名;
$document_uri       与$uri一样,URI地址;
$server_port        请求到达的服务器端口号;
2.2、Rewrite flag

rewrite  指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if 环境下,每行rewrite指令最后跟一个flag标记。

3、rewrite练习实例:

# 案例1:测试重写功能

server {
	listen 80;
	location /host {
		if ($arg_url ~ "baidu") {
			rewrite .*   https://www.baidu.com break;
		}	
		if ($arg_url ~ "taobao") {
			rewrite .*   https://www.taobao.com break;
		}
	}
}
#案例2本地解析host文件:http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.html

server {
	listen 80;
	location /a/1.html {
		rewrite /a/(.*)  /b/2.html;
	}
	location /b {
		root /usr/share/nginx/html/;
	}

}
# 案例3 :http://www.testpm.com/2019/a/1.html ==> http://www.testpm.com/2018/a/1.html   访问2019网页将会定向到2018目录

server {
	listen 80;
	location /2019 {
		rewrite /2019(.*)$  /2018$1;
	}
	location /2018 {
		root   /usr/share/nginx/html;
	}

}
# 案例4: http://www.qf.com/a/1.html ==> http://jd.com
server {
	listen 80;
	location /a/1.html {
		rewrite .*    http://jd.com;
	}
}
# 案例5:http://www.qf.com/a/1.html ==> http://jd.com/a/1.html

server {
	listen 80;
	location /a/1.html {
		rewrite (/a/.*)$  http://jd.com/$1;
	}


}
#案例6:http://www.tianyun.com/a/b/c  ==> http://www.tianyun.com/a/b/c/
# $1: /a/b
# $2: c
# http://$host$1$2$3/   在访问目录后添加/  (如果目录后已有/,则不加/)

server {
	listen 80;
	location /a {
		if ( -d $request_filename ) {
			rewrite ^(.*)([^/])$   http://$host$request_uri/   permanent;
	} 
		root /usr/share/nginx/html;
	} 


}
#案例7: http://www.tianyun.com/login/tianyun.html ==>  http://www.tianyun.com/reg/login.html?user=tianyun

server {
	listen 80;
	location /login {
		rewrite ^/login/(.*).html    /reg/login.html?user=$1;	
	}
	location /reg {
		root   /usr/share/nginx/html;
	}
}
#案例8:http://www.tianyun.com/qf/11-22-33/1.html  ==>  http://www.tianyun.com/qf/11/22/33/1.html


server {
	listen 80;
	location /qf {
		root /usr/share/nginx/html;
	rewrite ^/qf/(.*)-(.*)-(.*)/(.*)$  /qf/$1/$2/$3/$4  break;   
	}

}
# break 练习
server {
    listen       80;
    server_name  localhost;
    access_log  /var/log/nginx/last.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    
    location /break/ {
        root /usr/share/nginx/html;
        rewrite .* /test/break.html break;
    }
    location /last/ {
        root /usr/share/nginx/html;
        rewrite .* /test/last.html break;
        
    }
    location /test/ {
        root /usr/share/nginx/html;
        rewrite .* /test/test.html break;
    }

}
#匹配不同的搜索方式:
server {
    listen 80;

    location /abc {
        return 302 https://www.baidu.com;
    }
    location ~ /abc {
        return 302 https://www.taobao.com;
    }
    location ^~ /abc/ {
        return 302 https://www.jd.com;
    }
    location ~* /ABC {
        return 302 https://www.pingduoduo.com;
    }
    location = /abc {
        return 302 https://www.vip.com;
    }
}
# return用法,直接跳转到给的最终页面,前面加状态码,可以观察是否跳转成功。

server {
	listen 80;
	location / {
	return 200 www.baidu.com;
	}

}
#案例9:#http://alice.testpm.com ==> http://www.testpm.com/alice
#http://jack.testpm.com ==> http://www.testpm.com/jack



server {
	listen 80;
	location / {
		if ($host ~ www.testpm.com) { 
			break;
			}
		if ($host ~ ^(.*).testpm.com) {
			set $user $1;
			rewrite .*  http://www.testpm.com/$user;
		}
		rewrite .*   http://www.testpm.com/$1;
	}
	location /alice {
		root /opt/web;
		index index.html;
	}
	location /jack {
		root /opt/web;
		index index.html;
	}


}

4、set 指令是用于定义一个变量,并且赋值

编辑配置文件:
server {
    listen       80;
    server_name  www.testpm.com;  

    location / {
         root   /usr/share/nginx/html;
         index  index.html index.htm;
         if ( $host ~* ^www.testpm.com$) {   #如果是www开头,那么直接跳出本次if.
                break;
                }
         if ( $host ~* "^(.*)\.testpm\.com$" ) {    #如果网址行匹配的是其他内容开头,则使用set赋值,$user=$1,输入的第一个参数。
                set $user $1;
                rewrite .* http://www.testpm.com/$user permanent(永久跳转302);
                }
        }
    location /jack {
         root /usr/share/nginx/html;
         index  index.html index.hml;
        }
    location /alice {
         root /usr/share/nginx/html;
         index index.html index.hml;
        }
}

5、return 指令用于返回状态码给客户端

例10:80 ======> 443 :80转443端口


server {
    listen       80; 
    server_name  www.chaosaigc.com;
    access_log  /var/log/nginx/http_access.log  main;
    return 443 https://www.chaosaigc.com$request_uri;
}

6、last、break 练习

[root@localhost test]# cat /etc/nginx/conf.d/last_break.conf 
server {
    listen       80;
    server_name  localhost;
    access_log  /var/log/nginx/last.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    
    location /break/ {
        root /usr/share/nginx/html;
        rewrite .* /test/break.html break;
    }

    location /last/ {
        root /usr/share/nginx/html;
        rewrite .* /test/last.html break;
    }

    location /test/ {
        root /usr/share/nginx/html;
        rewrite .* /test/test.html break;
    }
}

注意:

  • last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求;

  • break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配;

  • 使用 alias 指令时,必须使用 last;

  • 使用 proxy_pass 指令时,则必须使用break。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值