什么是Rewrite?Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程。
• URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如:www.123.com/index.php?id=123使用URL Rewrite转换后可以显示为www.123.com/123.html
• 对于追求完美主义的网站设计师,就算是网页的地址也常望看起来尽量简洁明快。理论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所以,Url Rewrite可以让我们网贴的网页更容易被搜索引擎所收录。
• 从安全角度上讲,如果在URL中暴露太多的参数,无凝会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的UL地址可以给我们带来更高的安全性。
• 实现网站地址姚转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问taobao.com的80端口时,将其就转到443端口。
总结来说Rewrite的功能就是:使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。
• Nginx:通过ngx_http_rewrite_module模块支持url重写、支持if条件判断,但不支持else。
• 跳转:从一个location跳转到另一个location,循环最多可执行10次,吵过后nginx将返回500错误码。
• PCRE支持:perl兼容正则表达式的语法规则匹配。
• 重写模块set指令:创建新的变量并赋值。
rewrite
• regex:表示正则匹配规则。
• replacement:表示跳转后的内容。
• flag:表示rewrite支持的flag标记。
flag | 作用 |
---|---|
last | 停止所有rewrite相关指令,然后使用新的URL进行匹配;一般用在server和if中。(停止当前这个请求,并根据rewritel匹配的规则重新发起一个请求。新请求又从第一阶段开始执行) |
break | 停止所有rewrite相关指令,和last不同的是,last接着继续使用新的URl匹配location。而break则是直接使用当前的URl进行请求处理,能避免重复rewrite;一般用在location中 |
redirect | 返回302临时重定向,浏览器地址栏会显示跳转后的URL地址 |
permanent | 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址 |
其中相对于last,break并不会重新发起一个请求,只是跳过当前的rewrite阶段,并执行本请求后续的执行阶段。
字符 | 描述 |
---|---|
. | 匹配除换行符以外的任意字符 |
? | 匹配前面的字符零次或一次 |
+ | 匹配前面的字符一次或多次 |
* | 匹配前面的字符0次或多次 |
\d | 匹配一个数字字符。相当于[0-9] |
\ | 转义符 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
{n} | 匹配前面的字符n次 |
{n,} | 匹配前面的字词n次或更多次 |
[c] | 匹配单个字符c |
[a-z] | 匹配小写字母的任意一个 |
小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。
1.执行server块里而的rewrite指令。
2.执行location匹配。
3.执行选定的location中的rewrite指令。
使用regex匹配URI,并将匹配到的URI替换成新的URI(replacement)。如果有多个rewrite,执行顺序是从上到下依次执行,匹配到一个后匹配并不会终止,会继续匹配下去,直到返回最后一个匹配为止。如果想中途终止,则需要设置f1ag参数。
当然上面说的都是重写URI,如果placement中包含了任何协议相关,如:http://和https://,则请求就直接返回302重定向终止了。
当然,浏觉器在接收到30x的状态码后,会再度根据这个返回去请求rewrite之后的地址,最终得到所要的结果。如果不是30x的状态码,则属于nginx件内部跳转,浏览器不需要再度发起请求。
例:旧的域名有业务需求变更,需要使用新域名代替,但是旧域名不能弃用,需要跳转到新域名上,而且后面的参数保持不变。
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.demo.com; #域名修改
charset ntf-8; #识别中文
access_log logs/www.demo.com-.access.log; #日志修改
location / {
#添加域名和重定向
if ($host = 'www.demo.com'){
#$host为rewrite全局变量,代表请求主机头字段或主机名
rewrite ^/(.*)$ http://www.demottt.com/$1 permanent;
#$1为正则匹配的内容,即“域名/”之后的字符串,这里就是(.*)$
}
root html;
index index.html index.htm;
}
配置完成后验证,可以去windows主机中的hosts文件通过记事本打开添加dns解析:
验证在浏览器输入模拟访问http://www.demo.com/index.html是否会跳转到www.demottt.com/index.html:
例如:要求所有IP访问任何内容都显示一个固定的维护页面,除内部IP才能正常访问。
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.demo.com; #域名修改
charset ntf-8; #识别中文
access_log logs/www.demo.com-.access.log; #日志修改
#设置是否合法的IP标记
set $rewrite true; #设置变量rewrite,变量值为布尔值ture
#判断是否为合法IP
if ($remote_addr = "192.168.222.128") {
#当客户端IP为192.168.222.128时,将变量值设为false,不进行重写
set $rewrite false;
}
#除了合法IP,其他都是非法IP,进行重写跳转维护页面
if ($rewrite = ture) { #当变量值为true时
rewrite (.+) /wehui.html; #将域名后面的路径重写成/weihu.html
}
location = /weihu.html {
root /var/www/html; #网页返回/var/html/weihu.com的内容
}
location / {
root html;
index index.html index.htm;
}
#创建维护网页存放目录
[root@TTTTTTT ~]# mkdir -p /var/www/html/
#编译正在维护的页面
[root@TTTTTTT ~]# echo "It is not work
" > /var/www/html/weihu.html
#平滑重新加载nginx服务
[root@TTTTTTT ~]# nginx -s reload
重新登陆一个不同IP的主机:
登陆192.168.222.128网址查看是否被拦截:
例如:现在访问的是http://bbs.demo.com/post/,现在需要将这个域名下面的范根都跳转到http://www.demo.com/bbs/post
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name bbs.demo.com;
chater utf-8;
access_log /var/log/nginx/www.demo.com-access.log;
}
location /post {
rewrite (.+http://www.demo.com/bbs$1 permanent; #这里的$1为位置变量,代表/post
}
location /{
root html;
index index.html index.htm;
}
[root@TTTTTTT ~]# mkdir -p /usr/local/nginx/html/bbs/post
[root@TTTTTTT ~]# echo "this is 1.html">/usr/local/nginx/html/bbs/post/1.html
[root@TTTTTTT ~]# echo "192.168.10.19 bbs.kgc.com">>/etc/hosts
[root@TTTTTTT ~]# nginx -s reload
使用浏览器访问bbs.kgc.com/post/1.html跳转到www.kgc.com/bbs/post/1.html。
例:现在访问http://www.demo.com/100-(100|200)-100.html跳转到http://wwww.demo.com页面。
vim /usr/local/nginx/conf/nginx.conf
server
listen 80;
server name www.demo.com; #域名修改
charset utf-8;
access log /var/log/nginx/www.demo.com-access.log;
if($request uri ~ ^/100-(100|200)-(\d+).html$){
rewrite (.+http://www.demo.com permanent;
location / {
root html;
index index.html index.htm;
}
#$request uri:包含请求参数的原始URI,不包含主机名,如:http://www.kgc.com/abc/bbs/index.html?a=1&b=2/abc/bbs/index.php?a=18b=2
#uri:这个变量指当前的请求URI,不包括任何参数,如:/abc/bbs/index.html
#$document uri:与$uri相同,这个变量指当前的请求URI,不包括任何传递参数,如:/abc/bbs/index.html
例:访问www.demo.com/upload/index.php跳转www.demo.com。
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server name www.demo.com; #域名修改
charset utf-8:
access_log /var/log/nginx/www.demo.com-access.log;
location ~/upload/.*\.php$ {
rewrite (.+) http://www.demo.com permanent;
}
location / {
root html;
index index.html index.htm;
}
}
例:要求访问一个具体的页面如www.demo.com/abc/123.html。
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server name www.demo.com; #域名修改
charset utf-8:
access_log /var/log/nginx/www.demo.com-access.log;
location ~* ^/abc/123.html {
rewrite (.+) http:/www.demo.com permanent;
}
if (Srequest_uri ~ ^/abc)
location / {
root html;
index index.html index.htm;
}
}
END