URL地址重写(Rewrite)
一、什么是URL地址重写 (Rewrite )?
- URL Rewrite 最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术比如http://www.123.com/news/index.php?id=123 使用URLRewrite 转换后可以显示http://www.123.com/news/123.html 对于追求完美主义得网站设计时,就算是网页的地址也希望看起来尽量简洁明快,理论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页页面的评分一般要高于动态页面,所以,UrlRewrite可以让我们网站更容易被搜索引擎所收录
- 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄露,可能会被一些黑客利用,对你的系统造成一定的损坏,所以静态化的URL地址可以给我们带来更高的安全性
- 实现网站地址跳转,例如用户访问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 #当前请求的文件路径名(当网站的主目录)
$request_uri #当前请求的文件路径名(不带网站的主目录)
$scheme #用的协议,比如http或https
$server_name #请求到达的服务器名
$args #请求中的参数
$host #请求信息中的“Host”,如果请求中没有Host行,则等于设置的服务器名
$limit_rate
$request_method
$remote_port
$remote_user
$query_string
$server_protocol
$server_addr
$document_uri
$server_port
三、Rewrite flag
- break:停止用户的当前匹配
- last:当last出现,不会显示当前执行结果,而是让用户寻找下一个location匹配,或理解为跳过(隐藏)
四、Rewrite匹配参考示例
4.1 Rewrite 案例一
站内地址重写
#需求
当用户访问http://192.168.100.10/abc/a/1.html地址时,通过redirect重定向至http://192.168.100.10/ccc/bbb/2.html
一、还原默认站点(清空上一个实验的环境)
[root@lnmp ~]# yum remove -y nginx
[root@lnmp ~]# yum install -y nginx
[root@lnmp ~]# rm -rf /usr/share/nginx/html/* #清理环境
[root@lnmp ~]# vim /usr/share/nginx/html/index.html #创建主页文件
/usr/share/nginx/html/index.html #写入内容,证明这是默认主页文件
[root@lnmp ~]# systemctl restart nginx
二、配置地址重写
环境准备
[root@lnmp html]# pwd
/usr/share/nginx/html
[root@lnmp html]# mkdir -p abc/a/
[root@lnmp html]# echo abc/a/index.html > abc/a/1.html
[root@lnmp html]# mkdir /usr/share/nginx/html/ccc/bbb -p
[root@lnmp html]# vim /usr/share/nginx/html/ccc/bbb/2.html
ccc/bbb/2.html
配置地址重写
[root@lnmp ~]# vim /etc/nginx/nginx.conf
server { #server中进行添加
location /abc {
rewrite .* /ccc/bbb/2.html permanent; #.* 任意 表示不管输入什么地址都重写至2.html
}
...
[root@lnmp ~]# systemctl restart nginx
关于permanent:permanent会将地址显示为新的URL地址(重定向之后的地址)
三、访问旧页面进行测试
不添加permanent
http://192.168.100.10/abc/a/1.html
添加permanent
301页面重定向
四、总结一下
- 不添加permanent URL是老的,服务器内部转换请求,称为服务器内部转换
- 添加permanent URL被替换,生成两次请求,服务器只转换了url,客户端重新申请
4.2 Rewrite 案例二
#需求
利用正则中的"()和\1",替换url中的一部分内容
将http://192.168.100.10/2016/a/b/c/1.html
换http://192.168.100.10/2017/a/b/c/1.html
一、注释掉上一个实验中的重定向部分
避免实验出现交叉影响
# location /abc {
# rewrite .* /ccc/bbb/2.html permanent;
#}
二、配置地址重写
环境准备
[root@lnmp ~]# mkdir /usr/share/nginx/html/2017/a/b/c -p #不用配置2016因为地址会全部重定向
[root@lnmp ~]# vim /usr/share/nginx/html/2017/a/b/c/1.html
2017/a/b/c/1.html
配置地址重写
[root@lnmp ~]# vim /etc/nginx/nginx.conf
...
location /2016 {
rewrite ^/2016/(.*)$ /2017/$1 permanent; #$1 抽取前方括号内的$数据赋予2017
}
...
[root@lnmp ~]# systemctl restart nginx
三、访问旧页面进行测试
http://192.168.100.10/2016/a/b/c/1.html
4.3 Rewrite 案例三
#需求
location {rewrite} 只能替换url中的目录路径
使用if(){rewrite}可以替换协议主机目录全部内容
将http://www.pakho.com
换http://jd.com
一、注释掉上一个实验的重定向部分
环境清理
# location /2016 {
# rewrite ^/2016/(.*)$ /2017/$1 permanent;
# }
二、配置地址重写
...
if ( $host ~* pakho.com ){ #调用host变量 以不区分大小写的方法
rewrite .* http://jd.com permanent; #执行地址重写为jd.com
...
[root@lnmp ~]# systemctl restart nginx
三、访问旧页面进行测试
C:\Windows\System32\drivers\etc\hosts #本地域名解析
192.168.100.10 pakho.com
http://pakho.com
4.4 Rewrite 案例四
美化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/
一、注释掉上一个实验中的重定向部分
# if ( $host ~* pakho.com ){
# rewrite .* http://jd.com permanent;
# }
二、配置地址重写
...
if ( -d $request_filename ){ #判断用户执行的不是一个文件夹
rewrite ^(.*)([^/])$ http://$host$1$2/ permanent; #用户输入为.* 排除/
}
...
[root@lnmp ~]# systemctl restart nginx
三、访问页面进行测试
[root@lnmp html]# echo /usr/share/nginx/html/ccc/bbb/index.html > /usr/share/nginx/html/ccc/bbb/index.html #准备网站根目录
http://192.168.100.10/ccc/bbb
会自动添加/目录
4.5 Rewrite 案例五
#需求
目录的表达方式发送变化
原先“-”分隔,变成了“/”目录层次
将http://www.pakho.com/kgc/11-22-33/1.html
换http://www.pakho.com/kgc/11/22/33/1.html
一、注释掉上一个实验的重定向部分
# if ( -d $request_filename ){
# rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;
# }
二、配置地址重写
环境准备
[root@lnmp ~]# mkdir /usr/share/nginx/html/kgc/11/22/33/ -p
[root@lnmp ~]# echo '/usr/share/nginx/html/kgc/11/22/33/1.html' > /usr/share/nginx/html/kgc/11/22/33/1.html
...
location /kgc {
rewrite ^/kgc/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /kgc/$1/$2/$3$4 permanent; #+ 匹配前导符0-多次
}
...
[root@lnmp ~]# systemctl restart nginx
三、访问页面进行测试
http://192.168.100.10/kgc/11-22-33/1.html
4.6 Rewrite 案例六
#需求
引用原URL中的信息,重定向至目标的URL
http://alice.pakho.com ==> http://www.pakho.com/alice
http://jack.pakho.com ==> http://www.pakho.com/jack
一、注释掉上一个实验的重定向部分
# location /kgc {
# rewrite ^/kgc/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /kgc/$1/$2/$3$4 permanent;
# }
二、配置地址重写
...
if ( $host ~* "^www.pakho.com$" ){ #如下配置如果用户输入www.pakho.com也会将其赋予变量造成死循环
break; #设置匹配如果是以www开头则停止匹配
}
if ( $host ~* "^(.*)\.pakho\.com$" ){ #请求像是pakho的时候
set $user $1; #设置变量 变量名为$user $1为已有的位置变量 将$1赋值$user
rewrite .* http://www.pakho.com/$user permanent;
}
...
[root@lnmp ~]# systemctl restart nginx
三、访问页面进行测试
准备目标页面
[root@lnmp ~]# mkdir /usr/share/nginx/html/{alice,jack}
[root@lnmp ~]# echo "alice" > /usr/share/nginx/html/alice/index.html
[root@lnmp ~]# echo "jack" > /usr/share/nginx/html/jack/index.html
准备客户端DNS记录
C:\Windows\System32\drivers\etc\hosts
192.168.100.10 pakho.com www.pakho.com jack.pakho.com alice.pakho.com
访问
alice.pakho.com
jack.pakho.com
4.6 Rewrite 案例七:敏感文件处理方法
#目的
如果访问服务器中的特殊文件,如:.sh结尾的文件,则返回403操作拒绝错误
[root@lnmp ~]# echo 123 > /usr/share/nginx/html/1.sh
#访问
http://192.168.100.10/1.sh
一、设置屏蔽
... #位于server中
location ~* \.sh$ {
return 403; #return返回403
#return 301 http://www.pakho.com #或是重定向至主页
}
...
[root@lnmp ~]# systemctl restart nginx
二、访问页面进行测试
http://192.168.100.10/1.sh
实验完成!
五、总结一下
- 关于URL地址重写功能,实验中的步骤可能与生产环境中无差别,主要还是看客户的需求
- 让我比较困惑的应该是全局的变量,笔记中也有记录,应重在多操作多实验