一:什么是rewrite
rewrite是url重写,主要实现url地址重写,以及重定向,就是把传入web的请求重定向到其他url的过程
二:rewrite使用场景
1.url地址跳转,例如用户访问cxy.com将其跳转到baidu.com,或者当用户通过http的方式访问cxy.com时,将其跳转至https的方式访问cxy.com
2.url伪静态,将动态页面显示为静态页面的一种技术,便于搜索引擎的录入
3.搜索引擎SEO优化依赖于url路径,以便支持搜索引擎录入
4.可以调整用户浏览url,看起来更加规范,合乎开发及产品人员的需求
三:rewrite语法
关键字 正则表达式 代替的内容 重写类型
Syntax: rewrite regex replacement [flag];
Default: --
Context: server,location,if
在匹配过程中可以引用一些nginx的全局变量
例: http://localhost:88/test1/test2/test.php
$host: localhost
$server_port:88
$request_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php
四:开启nginx的rewrite日志功能
4.1 设置nginx的错误日志级别为notice
[root@web01-7 conf.d]# vim /etc/nginx/nginx.conf
user www;
worker_processes 1;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
4.2 在http模块层,开启rewrite_log日志
http {
.......
rewrite_log on;
.......
}
五:rewrite实例
5.1 用户访问cxy.com时跳转到百度
[root@web01-7 conf.d]# cat www.conf
server {
listen 80;
server_name test.cxy.com;
root /code/test/;
index index.html;
location / {
rewrite ^/ https://www.baidu.com;
}
}
测试访问http://test.cxy.com直接跳转到了www.baidu.com
5.2 用户访问/abc/1.html,实际上访问的是/cccc/bbb/2.html
先创建访问目录
[root@web01-7 test]# mkdir -p /code/test/cccc/bbb
[root@web01-7 test]# cd /code/test/cccc/bbb/
[root@web01-7 bbb]# cat 2.html
cccc bbb
配置rewrite跳转
[root@web01-7 bbb]# vim /etc/nginx/conf.d/www.conf
server {
listen 80;
server_name test.cxy.com;
root /code/test/;
index index.html;
# location / {
# rewrite ^/ https://www.baidu.com;
#}
location ~* /abc/1.html {
rewrite /abc/1.html /cccc/bbb/2.html;
}
}
测试:当访问test.cxy.com/abc/1.html的时候,跳转访问到了test.cxy.com/cccc/bbb/2.html
因为location ~*规则是忽略大小写,现在我们测试访问test.cxy.com/ABC/1.html,发现显示404没办法访问
优化配置一(匹配大小写后正常跳转):
[root@web01-7 bbb]# vim /etc/nginx/conf.d/www.conf
server {
listen 80;
server_name test.cxy.com;
root /code/test/;
index index.html;
# location / {
# rewrite ^/ https://www.baidu.com;
#}
location ~* /abc/1.html {
rewrite .* /cccc/bbb/2.html; ##不管浏览器上输入的是什么,只要是匹配到了~* /abc/1.html就跳转
}
}
[root@web01-7 bbb]# nginx -t
[root@web01-7 bbb]# systemctl reload nginx
测试访问test.cxy.com/ABC/1.html,访问正常
优化配置二(让状态能显示302状态码,这个也是最终配置)
[root@web01-7 bbb]# vim /etc/nginx/conf.d/www.conf
server {
listen 80;
server_name test.cxy.com;
root /code/test/;
index index.html;
# location / {
# rewrite ^/ https://www.baidu.com;
#}
location ~* /abc/1.html {
#rewrite .* /cccc/bbb/2.html redirect;
return 302 /cccc/bbb/2.html; #这个2个命令都是302跳转的命令,不要一起配置.配置一条即可
}
}
测试访问结果网页跳转并且显示了302状态码
5.3 用户访问/2018/ccc/bbb/2.html实际上真实访问的是/2014/ccc/bbb/2.html
先创建访问目录
[root@web01-7 bbb]# cd /code/test/
[root@web01-7 test]# mkdir 2014/ccc/bbb -p
[root@web01-7 test]# cat 2014/ccc/bbb/2.html
2014 cccc bbb
配置rewrite跳转
[root@web01-7 conf.d]# cat www.conf
server {
listen 80;
server_name test.cxy.com;
root /code/test/;
index index.html;
# location / {
# rewrite ^/ https://www.baidu.com;
#}
location ~* /abc/1.html {
#rewrite .* /cccc/bbb/2.html redirect;
return 302 /cccc/bbb/2.html;
}
location /2018 {
rewrite ^/2018/(.*)$ /2014/$1 redirect; #以根开始/2018下面的xxx,都跳到2014对应的目录xxx
}
}
测试访问:
5.4 用户访问/cxy目录下的任何内容,实际上真实访问的是http://baidu.com
[root@web01-7 test]# cat /etc/nginx/conf.d/www.conf
server {
listen 80;
server_name test.cxy.com;
root /code/test/;
index index.html;
location /cxy {
rewrite (.*) http://baidu.com redirect;
}
}
5.5 用户访问cxy-11-22-33.html.实际上真实访问的是/cxy/11/22/33/cxy_33.html
先创建访问目录
[root@web01-7~]#mkdir /code/test/cxy/11/22/33/ -p
[root@web01-7 33]# vim cxy_33.html
11 22 33 cxy
配置rewrite跳转
[root@web01-7 33]# vim /etc/nginx/conf.d/www.conf
server {
listen 80;
server_name test.cxy.com;
root /code/test/;
index index.html;
location / {
rewrite ^/(.*)-(.*)-(.*)-(.*).html /$1/$2/$3/$4/$1_$4.html redirect;
}
}
测试访问:成功跳转
5.6 将http请求,跳转至https
server {
listen 80;
server_name test.cxy.com
rewrite ^(.*) https://$server_name$1 redirect;
# return 302 https://$server_name$request_uri;
}
server {
listen 443;
server_name test.cxy.com
ssl on;
}
六:flag的区别
根据rewrite语法
关键字 正则表达式 代替的内容 重写类型
Syntax: rewrite regex replacement [flag];
Default: --
Context: server,location,if
每个rewrite都会跟一个flag
flag可以有如下参数
- last:停止处理后续rewrite指令集,然后对当前重写的新url在rewrite指令集上重新查找;浏览器地址栏URL地址不变
- break:停止处理后续rewrite指令集,并不在重新查找;浏览器地址栏URL地址不变
- redirect:302临时重定向,浏览器地址会显示重写后的URL地址
- permant:301永久重定向,浏览器地址会显示重写后的URL地址
6.1 重写配置
[root@web01-7 test]# vim /etc/nginx/conf.d/break_test.conf
server {
listen 80;
server_name rewrite.cxy.com;
root /code;
location / {
index index.html index.htm;
}
location /break/ {
rewrite ^/break/(.*) /test/$1 break;
return 402;
}
location /last/ {
rewrite ^/last/(.*) /test/$1 last;
return 403;
}
location /test/ {
return 508;
}
# 临时重定向
location /redirect {
rewrite ^ http://www.crane.run redirect;
}
# 永久重定向
location /permanent {
rewrite ^ http://www.crane.run permanent;
}
}
6.2 测试last和break
当访问rewrite.cxy.com/last/时,返回508
当访问rewrite.cxy.com/break/时,返回404
原因:break和last都停止处理后续rewrite指令集,不同之处在于last会重新发起新的请求.而break不会.当请求break时,如果匹配内容存在的话,可以直接请求成功,返回200;而如果请求内容不存在,则返回404.当请求last的时候.会对重写的新url重新发起请求,所以匹配到了return 508.
6.3 测试redirect和permanent
访问rewrite.cxy.com/redirect,返回302跳转
访问rewrite.cxy.com/permanent,返回301跳转
停止nginx ,再次测试
访问rewrite.cxy.com/redirect和rewrite.cxy.com/permanent
redirect和permanent的区别
- 服务器配置好redirect和permanent之后,打开浏览器分别访问这两个请求地址,然后停止Nginx服务。这时再访问redirect请求会直接报出无法连接的错误。但是permanent请求是永久重定向,浏览器会忽略原始地址直接访问永久重定向之后的地址,所以请求仍然成功。(这个验证不能禁用浏览器的缓存,否则即使是permanent重定向,浏览器仍然会向原始地址发出请求验证之前的永久重定向是否有效)
- 对于搜索引擎来说,搜索引擎在抓取到301永久重定向请求响应内容的同时也会将原始的网址替换为重定向之后的网址,而对于302临时重定向请求则仍然会使用原始的网址并且可能会被搜索引擎认为有作弊的嫌疑。所以对于线上正式环境来讲,尽量避免使用302跳转