十四、Rewrite指令及flag

一、概述

1、Rewrite

什么是Rewrite
1. URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如 http://www.123.com/news/index.php?
id=123 使用URLRewrite 转换后可以显示为 http://www.123 .com/news/123.html对于追求完美主义的网站设计师,就算是网页的地址也希望
看起来尽量简洁明快。 理论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所 以,UrlRewrite可以让
我们网站的网页更容易被搜索引擎所收录。
2. 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客 利用,对你的系统造成一定的破坏,所以静态
化的URL地址可以给我们带来更高的安全性。
3. 实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。

Rewrite相关指令
重定向: rewrite 将用户的访问(url),更换成指定的文件。
if 语句: 应用环境:server,location,语法:if (condition) { … }
条件判断:
~* 正则匹配 (不区分大小写)
!~ 非正则匹配 (区分大小写)
!~* 非正则 匹配 (不区分大小写)
-f 和!-f 用来判断是否存在文件
-d 和!-d 用来判断是否存在目录
-e 和!-e 用来判断是否存在文件或目录
-x 和!-x 用来判断文件是否可执行

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

2、flag

Rewrite flag
每行rewrite指令最后跟一个flag标记,支持的flag标记有:
last
停止处理当前ngx_http_rewrite_module,从指令之后的一个新的位置改变URI匹配搜索;
break
本条规则匹配完成后,终止匹配,不再匹配后面的规则
redirect
返回302临时重定向,浏览器地址会显示跳转后的URL地址
redirect url permanent
返回301永久重定向,浏览器地址会显示跳转后URL地址

redirect 和 permanent区别则是返回的不同方式的重定向,对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,
如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。
使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址
栏不会更改,那么很有可能出现URL劫持的现像。

二、Rewrite部分案例

1、重定向页面路径

当用户访问http://192.168.19.100/abc/a/1.html 地址时,
通过redirect 重定向至http://192.168.19.100/ccc/bbb/2.html

vim /etc/nginx/conf.d/default.conf
location /abc {
rewrite .* /ccc/bbb/2.html permanent;
#permanent 会将地址显示为新的URL地址(重定向之后的URL)
#添加上permanent,url被替换生成两次请求。服务器只转换了url,客户端重新申请
#不添加permanent,url是老的服务器内部转换请求。服务器内部转换URL,内部转换页面。
}



location /abc {
return 301 /ccc/bbb/2.html;
}

systemctl restart nginx

Location = /abc
通过此URL:http://192.168.100.10/abc/123.html访问服务器,结果是否会重定向
不可行。因为需要完全匹配
Location ~ /abc
通过此URL:http://192.168.100.10/abc/123.html访问服务器,结果是否会重定向
可行。因为部分匹配即可
Location ^~ /abc
通过此URL:http://192.168.100.10/abc/123.html访问服务器,结果是否会重定向
可行。因为部分匹配即可
阻止这样的url重定向
location ~ ^/abc
404

2、替换url中一部分的内容

利用正则中的”()和1 “,
替换url中一部分的内容。
将http://192.168.19.100/2016/a/b/c/1.html
换http://192.168.19.100/2017/a/b/c/1.html

vim /etc/nginx/conf.d/default.conf
location /2016 {
rewrite ^/2016(.*)$ /2017/$1 permanent;
#^/2016(.*)$: 以/2016开头任意字符结尾
}

3、替换协议主机目录全部内容

location { rewrite } 只能替换url中的目录路径,
使用if (){rewrite}可以替换协议主机目录全部能容。
将http://www.baidu.com
换http://jd.com

vim /etc/nginx/conf.d/default.conf
if ( $host ~* baidu.com ) {
#请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名
#~* 正则匹配 (不区分大小写)
rewrite .* http://jd.com permanent;
}

4、替换掉域名中的主机保留后端url路径

不论输入的url中页面内容是什么:
http://www.baidu.com/1.html
http://www.baidu.com/2.html
其结果。把主机地址由www.baidu.com换成cloud.com。$request全部都重定向至
http://cloud.com/1.html主页。
http://cloud.com/2.html
如果希望替换掉域名中的主机,保留后端url路径。可以使用nginx内置变量调用老的url目录路径。
示例
将http://www.baidu.com/ccc/bbb/2.html
换成http://cloud.com/ccc/bbb/2.html

vim /etc/nginx/conf.d/default.conf

if ( $host ~* baidu.com ){
rewrite .* http://cloud.com$request_uri permanent;
}

systemctl restart nginx

5、访问目录URL自动添加“/”

在访问的url是目录时,在URL自动添加一个“/”  (如果不是目录,则不加/)
(但是先做个判断,是目录才需要加,不是目录就不加。)
当用户访问网站时,输入的URL不完整。
1.输入的URL是目录时,自动添加“/”
http://www.baidu.com/abc
2.输入的URL是文件时,不添加“/”
http://www.baidu.com/abc/index.html
3.输入的URL是目录,但已经添加"/"时,不添加“/”
http://www.baidu.com/abc/

vim /etc/nginx/conf.d/default.conf
if (-d $request_filename) {
rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;
}

#-d:检查文件目录
#$request_filename:当前请求的文件路径名
#^(.*)([^/])$:任意字符开头,不是/结尾
#$host:请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名
systemctl restart nginx

将旧url中的字段,引入重定向后新url中
http://www.tianyun.com/login/tianyun.html
转为
http://www.tianyun.com/reg/login.php?user=tianyun
引用‘tianyun’关键字
复制
location /login {
rewrite ^/login/(.*).html$ /reg/login.php?user=$1;
}

6、“/"分割目录层次

目录的表达方式发生变化。
原先的“-”分割,变成了"/"目录层次。

http://www.tianyun.com/qf/11-22-33/1.html
转换为
http://www.tianyun.com/qf/11/22/33/1.html

vim /etc/nginx/conf.d/default.conf
location /00 {
rewrite ^/00/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /00/$1/$2/$3$4 permanent;
root /usr/share/nginx/html;
}

systemctl restart nginx

7、原URL中的信息重定向至目标的URL

引用原URL当中的信息,重定向至目标的URL
#http://alice.111.com ==> http://www.111.com/alice
#http://jack.111.com ==> http://www.111.com/jack

vim /etc/nginx/conf.d/default.conf
if ($host ~* "^www.111.com$" ) {
break;
}

if ($host ~* "^(.*).111.com$") {
set $user $1;
rewrite .* http://www.111.com/$user permanent;
}

#break:跳出循环,如不加break每一次重写后,主机名都符合if的判断结果,会再次被重写
#set 指令是用于定义一个变量,并且赋值。应用于server,location,if环境。

systemctl restart nginx

8、访问特殊文件返回403

如果访问服务器中的特殊文件。如:.sh结尾的文件。则返回403操作拒绝错误
vim /etc/nginx/conf.d/default.conf
location ~* .sh$ {
return 403;
#return 301 http://www.qianfeng.com;
}

9、 last 和 break标记 

last标记在本条rewrite规则执行完后,会对其所在的server { … } 标签重新发起请求;
break标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配。

另有些时候必须使用last,比如在使用alias指令时,而使用proxy_pass指令时则必须使用break。
如果location中rewrite后,还需要进行其他处理,如动态fastcgi请求(.PHP,.jsp)等,要用last继续发起新的请求
根的location使用last比较好, 因为如果有.php等fastcgi请求还要继续处理

mkdir /usr/share/nginx/html/test
echo 'break' > /usr/share/nginx/html/test/break.html
echo 'last' > /usr/share/nginx/html/test/last.html
echo 'test' > /usr/share/nginx/html/test/test.html

vim /etc/nginx/conf.d/default.conf
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.php;
}

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

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

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

elinks ip/break
结果为break
elinks ip/last
结果为test
elinks ip/test
结果为test

10、Rewrite - apache 开启重定向,开启443

vim /etc/httpd/conf.d/discuz.conf
<VirtualHost *:80>

RewriteEngine on
RewriteRule ^(.*)$ https://www.xuleicloud.top$1 [R=301,L]
</VirtualHost>
发表评论

相关文章