1、基本概述
1.1 什么是rewrite
Rewrite主要实现url地址重写, 以及地址重定向,就是将用户请求web服务器的地址重新定向到其他URL的过程。
1.2 Rewrite使用场景
1.2.1 地址跳转
用户访问www.xuliangwei.com/class这个URL时,将其定向至一个新的域名class.xuliangwei.com
1.2.2 协议跳转
用户通过http协议请求网站时,将其重新跳转至https协议方式
1.2.3 伪静态
将动态页面显示为静态页面方式的一种技术, 便于搜索引擎的录入, 同时减少动态URL地址对外暴露过多的参数, 提升更高的安全性。
1.2.4 搜索引擎
SEO优化依赖于url路径, 好记的url便于支持搜索引擎录入
2、Rewrite配置
2.1 语法规则
#rewrite表达式可以应用在server,location, if标签下
Syntax: rewrite regex replacement [flag];
Default: --
Context: server, location, if
#用于切换维护页面场景
#rewrite ^(.*)$ /page/wh.html break;
2.2 标记Flag
rewrite指令根据表达式来重定向URI,或者修改URI字符串。
每行rewrite指令最后跟一个flag标记,支持的flag标记有如下表格所示:
| flag | 描述 |
| —- | —- |
| last | 本条规则匹配完成后,停止匹配,不在匹配后面的规则 |
| break | 本条规则匹配完成后,停止匹配,不在匹配后面的规则 |
| redirect | 返回302临时重定向, 地址栏会显示跳转后的地址, 爬虫不会更新URL |
| permanent | 返回301永久重定向, 地址栏会显示跳转后的地址, 爬虫会更新URL |
break和last一样都会停止处理后续rewrite模块指令的运行,但是last会重新发起一个请求,无论请求成功或者失败,并重新匹配location。
1.last与break区别对比示例
[root@bgx conf.d]# cat rewrite.conf
server {
listen 80;
server_name rewrite.oldboy.com;
root /code;
location ~ ^/break {
rewrite ^/break /test/ break;
}
location ~ ^/last {
rewrite ^/last /test/ last;
}
location /test/ {
return 200 'ok';
}
}
#重启Nginx服务
[root@bgx conf.d]# systemctl restart nginx
2.使用浏览器访问/break测试
3.使用浏览器访问/last测试
4.last和 break 都是一个作用,都是表示停止rewrite规则,那last和break区别在哪呢
break匹配到规则,则会去本地路径中目录中寻找对应请求的文件。
last匹配到规则,会对其所在的server{…}标签重新发起请求。
所以,在访问/break和/last请求时,虽然对应的请求目录/test都是不存在了,理论上都应该返回404,但是实际请求/last的时候,是会有后面localtion所匹配到的结果返回的,如果last匹配不到location的结果则在返回错误。
5.redirect与permanent区别对比示例
[root@Nginx ~]# cat /etc/nginx/conf.d/rewrite.conf
server {
listen 80;
server_name rewrite.oldboy.com;
root /code;
location ~ ^/bgx {
rewrite ^(.*)$ https://www.xuliangwei.com redirect;
rewrite ^(.*)$ https://www.xuliangwei.com permanent;
#return 301 http://kt.xuliangwei.com;
#return 302 http://kt.xuliangwei.com;
}
}
6.通过浏览器访问,redirect会进行302跳转
7.使用 systemctl stop nginx停止nginx,然后再次访问网站测试 redirect
8.通过浏览器访问,permanent会进行301跳转
9.使用 systemctl stop nginx停止nginx,然后再次访问网站测试 permanent
3、规则实践
例1:
用户访问/abc/1.html
实际上真实访问是/ccc/bbb/2.html
#http://www.bgx.com/abc/1.html ==> http://www.bgx.com/ccc/bbb/2.html
#1.准备真实的访问路径
[root@web03 ~]# mkdir /code/ccc/bbb -p
[root@web03 ~]# echo "ccc_bbb_2" > /code/ccc/bbb/2.html
#2.Nginx跳转配置
[root@web03 conf.d]# cat ccbb.conf
server {
listen 80;
location / {
root /code;
index index.html;
}
location /abc {
rewrite (.*) /ccc/bbb/2.html redirect;
#return 302 /ccc/bbb/2.html;
}
}
#3.重启Nginx服务
[root@web03 ~]# systemctl restart nginx
例2:
用户访问_/2018/ccc/bbb/2.html_
实际上真实访问是_/2014/ccc/bbb/2.html_
#http://www.bgx.com/2018/ccc/bbb/2.html ==> http://www.bgx.com/2014/ccc/bbb/2.html
#1.准备真实的访问路径
[root@web03 ~]# mkdir /code/2014/ccc/bbb -p
[root@web03 ~]# echo "2014_ccc_bbb_2" > /code/2014/ccc/bbb/2.html
#2.Nginx跳转配置
[root@web03 conf.d]# cat ccbb.conf
server {
listen 80;
location / {
root /code;
index index.html;
}
location /2018 {
rewrite ^/2018/(.*)$ /2014/$1 redirect;
}
}
#3.重启Nginx服务
[root@web03 ~]# systemctl restart nginx
例3:
用户访问_/test_
目录下任何内容, 实际上真实访问是http://www.xuliangwei.com
location /test {
rewrite (.*) http://www.xuliangwei.com redirect;
}
例4:
用户访问_course-11-22-33.html_
实际上真实访问是_/course/11/22/33/course_33.html_
#http://www.bgx.com/course-11-22-33.html ==> http://www.bgx.com/course/11/22/33/course_33.html
#1.准备真实的访问路径
[root@web03 ~]# mkdir /code/course/11/22/33/ -p
[root@web03 ~]# echo "Curl docs.etiantian.org" > /code/course/11/22/33/course_33.html
#2.Nginx跳转配置
[root@web03 conf.d]# cat ccbb.conf
server {
listen 80;
root /code;
index index.html;
location / {
#灵活
rewrite ^/course-(.*)-(.*)-(.*).html$ /course/$1/$2/$3/course_$3.html redirect;
#固定
#rewrite ^/course-(.*) /course/11/22/33/course_33.html redirect;
}
#3.重启Nginx服务
[root@web03 ~]# systemctl restart nginx
例5:
将_http_
请求,跳转至_https_
server {
listen 80;
server_name bgx.com;
rewrite ^(.*) https://$server_name$1 redirect;
#return 302 https://$server_name$request_uri;
}
server {
listen 443;
server_name bgx.com;
ssl on;
}
4、规则补充
4.1 优先级
- $server_name 当前用户请求的域名
- $request_filename 当前请求的文件路径名(带网站的主目录/code/images/test.jpg)
- $request_uri 当前请求的文件路径名(不带网站的主目录/images/test.jpg)
- $scheme 用的协议,比如http或者https
4.3 如何优雅的书写Rewrite规则
server { listen 80; server_name www.oldboyedu.com oldboyedu.com; if ($http_host = oldboyedu.com){ rewrite (.*) http://www.nginx.org$1; } } #推荐的书写格式 server { listen 80; server_name oldboyedu.com; rewrite ^ http://www.oldboyedu.com$request_uri; } server { listen 80; server_name www.oldboyedu.com; }