四:Nginx Rewrite 模块
ngx_http_rewrite_module 包含的指令:
- if
- set
- break
- return
- rewrite_log
- rewrite
4.1:if 条件判断
4.1.1:文件判断
测试 if 语句,访问的资源存在则显示 “file exists.”,不存在则显示 “file doesn’t exist.”;
- 编辑配置文件:
server {
……
location /echo {
root /data/nginx/yqc/www;
default_type text/html;
if ( -f $request_filename ) {
echo "file exists.";
}
if ( !-f $request_filename ) {
echo "file doesn't exist.";
}
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 准备测试文件:
[root@node106 ~]# cp /etc/fstab /data/nginx/yqc/www/echo/fstab.html
- 测试访问存在的资源:
- 测试访问不存在的资源:
4.1.2:条件判断
判断访问所用协议,如果是 http,则显示 “if_http: http”,如果是 https,则显示 “if_https: https”;
- 编辑配置文件:
server {
……
location /echo {
root /data/nginx/yqc/www;
default_type text/html;
# if ( -f $request_filename ) {
# echo "file exists.";
# }
# if ( !-f $request_filename ) {
# echo "file doesn't exist.";
# }
if ( $scheme = http ) {
echo "if_http: $scheme";
}
if ( $scheme = https ) {
echo "if_https: $scheme";
}
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
https://www.yqc.com/echo/fstab.html
4.2:set 自定义变量
- 编辑配置文件:
server {
……
location /echo {
root /data/nginx/yqc/www;
default_type text/html;
set $name www.yqc.com;
set $nginx_port $server_port;
echo "$name:$nginx_port";
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
4.3:break 中断
测试 break 只会中断同一 location 中的 ngx_http_rewrite_module 模块中的指令,其它指令则继续运行;
- 编辑配置文件:
server {
……
location /echo {
root /data/nginx/yqc/www;
default_type text/html;
set $name www.yqc.com;
echo $name;
break;
set $nginx_port $server_port;
echo "$name:$nginx_port";
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
break 并未中断后边的 echo 指令,但却中断了后边的 set 指令,使得显示时 $nginx_port 的值为空;
4.4:return
测试 return 只会中断同一作用区域的所有指令,对自身所在作用区域之外的指令没有影响;
4.4.1:return in if
- 编辑配置文件:
server {
……
location /echo {
root /data/nginx/yqc/www;
default_type text/html;
if ( -f $request_filename ) {
echo "file exists.";
return 666 "return test";
}
if ( !-f $request_filename ) {
echo "file doesn't exist.";
}
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问存在的资源:
返回 return 的提示信息,并返回状态码 666;
- 访问不存在的资源:
echo 指令正常显示;
4.4.2:return in location
测试将 return 上提一层,放在 location 中的效果;
- 编辑配置文件:
server {
……
location /echo {
root /data/nginx/yqc/www;
default_type text/html;
echo "return failed.";
if ( -f $request_filename ) {
echo "file exists.";
}
if ( !-f $request_filename ) {
echo "file doesn't exist.";
}
return 666 "return test";
echo "return failed.";
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
该 location 中的所有 echo 指令均未执行;
访问 server 下的其它资源,不受影响;
4.4.3:return in server
继续上提一层,放在 server 中,测试该 server 的其它页面是否可以访问;
- 编辑配置文件:
[root@node106 ~]# cat /apps/nginx/conf.d/www.yqc.com.conf
server {
# listen 192.168.1.106:80;
listen 192.168.1.106:443 ssl;
server_name www.yqc.com;
ssl_certificate /apps/nginx/ssl/www.yqc.com.crt;
ssl_certificate_key /apps/nginx/ssl/www.yqc.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
error_page 500 502 503 504 404 /error.html;
access_log /data/nginx/logs/www-yqc-com_access_json.log format2;
error_log /data/nginx/logs/www-yqc-com_error.log;
gzip on;
gzip_comp_level 3;
gzip_min_length 1k;
gzip_types text/plain application/javascript application/x-javascript text/cssapplication/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
location / {
root /data/nginx/yqc/www;
index index.html;
}
location = /error.html {
root /data/nginx/yqc/redirect;
}
location = /status {
stub_status;
allow 192.168.1.0/24;
allow 127.0.0.1;
deny all;
}
location = /favicon.ico {
root /data/nginx/yqc/www/images;
#log_not_found off;
access_log off;
expires 90d;
}
location /echo {
root /data/nginx/yqc/www;
default_type text/html;
echo "return failed.";
if ( -f $request_filename ) {
echo "file exists.";
}
if ( !-f $request_filename ) {
echo "file doesn't exist.";
}
echo "return failed.";
}
return 666 "return test";
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 测试访问:
访问该 server 的所有资源,均返回 666;
4.5:rewrite_log
开启 rewrite 模块日志,查看相应日志内容;
- 开启 rewrite_log,并设置 error_log 的级别为 notice:
[root@node106 ~]# cat /apps/nginx/conf.d/www.yqc.com.conf
server {
……
error_log /data/nginx/logs/www-yqc-com_error.log notice;
……
location /echo {
root /data/nginx/yqc/www;
default_type text/html;
rewrite_log on;
set $name www.yqc.com;
echo $name;
break;
set $nginx_port $server_port;
echo "$name:$nginx_port";
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问并触发 break 指令,查看日志:
https://www.yqc.com/echo
[root@node106 ~]# tail -f /data/nginx/logs/www-yqc-com_error.log
2020/12/03 17:00:53 [warn] 21064#0: *31 using uninitialized "nginx_port" variable, client: 192.168.1.9, server: www.yqc.com, request: "GET /echo HTTP/1.1", host: "www.yqc.com"
4.6:rewrite 重定向
4.6.1:redirect 临时重定向
将 wap.yqc.com 临时重定向至 www.baidu.com,查看响应状态码;
- 编辑配置文件:
[root@node106 ~]# vim /apps/nginx/conf.d/wap.yqc.com.conf
server {
# listen 192.168.1.106:80;
listen 192.168.1.106:443 ssl;
server_name wap.yqc.com;
ssl_certificate /apps/nginx/ssl/wap.yqc.com.crt;
ssl_certificate_key /apps/nginx/ssl/wap.yqc.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
location / {
root /data/nginx/yqc/wap;
index index.html;
rewrite / http://www.baidu.com redirect;
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问并查看响应状态码:
4.6.2:permanent 永久重定向
将 wap.yqc.com 永久重定向至 www.baidu.com,查看响应状态码;
永久重定向会缓存 A 记录,即浏览器会保存此次 DNS 的解析记录;而临时重定向则不会;
- 编辑配置文件:
[root@node106 ~]# vim /apps/nginx/conf.d/wap.yqc.com.conf
server {
# listen 192.168.1.106:80;
listen 192.168.1.106:443 ssl;
server_name wap.yqc.com;
ssl_certificate /apps/nginx/ssl/wap.yqc.com.crt;
ssl_certificate_key /apps/nginx/ssl/wap.yqc.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
location / {
root /data/nginx/yqc/wap;
index index.html;
# rewrite / http://www.baidu.com redirect;
rewrite / http://www.baidu.com permanent;
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问并查看响应状态码:
4.6.3:标记 break 后的单次重写
测试场景:
- 访问 /break 开头的 URI,重写到 /test1 后标记 break;
- 同一个 location 中,在重写到 /test1 的指令后添加一条重写到 /test2 的指令(测试 break 后不会执行同一 location 中的 rewrite 指令);
- 在 /test1 的 location 中添加一条 rewrite 指令,重写至 /test3,(测试 break 后也会执行新的 URI 匹配到的 location 中的 rewrite 指令);
- 编辑 URI 重写规则:/break–>/test1–>/test2–>/test3,全部标记为 break(测试标记为 break 的重写 URI 只会再被 rewrite 一次,即这次连续重写只会进行到 test2);
- 将 /test1 的location 中的 rewrite 指回 /break(测试 break 不会出现循环重写);
break 后不执行同一 location 的其它 rewrite
- 编辑配置文件(测试从 /break 重写至 /test1 后,不会执行同一 location 中重写至 /test2 的指令):
[root@node106 ~]# vim /apps/nginx/conf.d/wap.yqc.com.conf
server {
listen 192.168.1.106:80;
server_name wap.yqc.com;
location / {
root /data/nginx/yqc/wap;
index index.html;
}
location /break {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/break/(.*) /test1/$1 break;
rewrite ^/test1/(.*) /test2/$1 break;
}
location /test1 {
root /data/nginx/yqc/wap;
index index.html;
}
location /test2 {
root /data/nginx/yqc/wap;
index index.html;
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 准备测试页面:
[root@node106 ~]# mkdir /data/nginx/yqc/wap/{break,test1,test2,test3}
[root@node106 ~]# vim /data/nginx/yqc/wap/break/index.html
break page
[root@node106 ~]# vim /data/nginx/yqc/wap/test1/index.html
test1 page
[root@node106 ~]# vim /data/nginx/yqc/wap/test2/index.html
test2 page
[root@node106 ~]# vim /data/nginx/yqc/wap/test3/index.html
test3 page
- 访问测试 break 后不会执行同一 location 中的其它 rewrite 指令:
只重写至 /test1;
[root@node105 ~]# curl -L http://wap.yqc.com/break/
test1 page
标记为 break 的新 URI 会重新匹配 location
- 编辑配置文件,在 location /test1 中添加重写至 /test3 的 rewrite 指令:
[root@node106 ~]# cat /apps/nginx/conf.d/wap.yqc.com.conf
server {
listen 192.168.1.106:80;
server_name wap.yqc.com;
error_log /data/nginx/logs/wap-yqc-com_error.log notice;
rewrite_log on;
location / {
root /data/nginx/yqc/wap;
index index.html;
}
location /break {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/break/(.*) /test1/$1 break;
rewrite ^/test1/(.*) /test2/$1 break;
}
location /test1 {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/test1/(.*) /test3/$1 break;
}
location /test2 {
root /data/nginx/yqc/wap;
index index.html;
}
location /test3 {
root /data/nginx/yqc/wap;
index index.html;
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
重写流程:break–>test1–>test3;
[root@node105 ~]# curl -L http://wap.yqc.com/break/
test3 page
break 的重写 URI 只会再被重写一次
- 编辑配置文件:
重写流程:break–>test1–>test2–>test3
[root@node106 ~]# vim /apps/nginx/conf.d/wap.yqc.com.conf
server {
listen 192.168.1.106:80;
server_name wap.yqc.com;
error_log /data/nginx/logs/wap-yqc-com_error.log notice;
rewrite_log on;
location / {
root /data/nginx/yqc/wap;
index index.html;
}
location /break {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/break/(.*) /test1/$1 break;
}
location /test1 {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/test1/(.*) /test2/$1 break;
}
location /test2 {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/test2/(.*) /test3/$1 break;
}
location /test3 {
root /data/nginx/yqc/wap;
index index.html;
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
重写至进行到 test2 即停止;
[root@node105 ~]# curl -L http://wap.yqc.com/break/
test2 page
- 查看 rewrite 日志:
2020/12/03 23:18:31 [notice] 21902#0: *11 "^/break/(.*)" matches "/break/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /break/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:18:31 [notice] 21902#0: *11 rewritten data: "/test1/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /break/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:18:31 [notice] 21902#0: *11 "^/test1/(.*)" matches "/test1/index.html", client: 192.168.1.105, server: wap.yqc.com, request: "GET /break/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:18:31 [notice] 21902#0: *11 rewritten data: "/test2/index.html", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /break/ HTTP/1.1", host: "wap.yqc.com"
break 可以防止重写循环
- 将 location /test1 中的 rewrite 规则指回 /break:
现在的 rewrite 规则形成一个循环;
location /break {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/break/(.*) /test1/$1 break;
rewrite ^/test1/(.*) /test2/$1 break;
}
location /test1 {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/test1/(.*) /break/$1 break;
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
两条 rewrite 规则在这次请求中都只执行了一次,URI 被重新指回 /break;
[root@node105 ~]# curl -L http://wap.yqc.com/break/
break page
- 查看重写日志:
[root@node106 ~]# tail -f /data/nginx/logs/wap-yqc-com_error.log
2020/12/03 19:08:03 [notice] 21605#0: *9 "^/break/(.*)" matches "/break/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /break/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 19:08:03 [notice] 21605#0: *9 rewritten data: "/test1/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /break/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 19:08:03 [notice] 21605#0: *9 "^/test1/(.*)" matches "/test1/index.html", client: 192.168.1.105, server: wap.yqc.com, request: "GET /break/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 19:08:03 [notice] 21605#0: *9 rewritten data: "/break/index.html", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /break/ HTTP/1.1", host: "wap.yqc.com"
4.6.4:标记 last 后的多次重写
last 实际应用场景不多;
测试场景:
- 同一个 location 中,在重写到 /test1 的指令后添加一条重写到 /test2 的指令(测试 break 后不会执行同一 location 中的 rewrite 指令);
- 编辑 URI 重写规则:/last–>/test1–>/test2–>/test3–>/test4–>/test5,全部标记为 last(测试标记为 last 的重写 URI 会被连续重写多次,直至所有重写规则流程结束);
- 编辑 URI 重写规则:/last–>/test1–>/last……,标记为 last(测试 last 可能导致的重写循环);
- 模拟需要多次重写的应用场景:
appv1 改版为 appv2,后又改版为 appv3,此时如果想让仍保留着 appv1 访问路径的用户,直接访问 appv3,通过连续两个标记 break 的 rewrite 规则即可实现,即 /appv1–> /appv2 --> /appv3,因为第一次 rewrite 后生成的新 URI(/appv2 )还能在经过一次 rewrite,从而重写为 appv3;
然而如果再进行了一次版本升级,想让用户通过 /appv1 访问到 /appv4,就要通过 last 来实现多次重写了;
P.S.
当然,这种应用场景基本遇不到,因为实际中只需添加 /appv1 --> /appv4 的 rewrite 规则即可,不需要连续重写;
顶多再分别单独添加 /appv2 --> /appv4、 /appv3 --> /appv4 的 rwrite 规则,即可将所有旧版本的 URL 重定向至新版本;
last 后同样不会执行同一 location 的其它 rewrite 规则
- 编辑配置文件:
[root@node106 ~]# vim /apps/nginx/conf.d/wap.yqc.com.conf
server {
listen 192.168.1.106:80;
server_name wap.yqc.com;
location / {
root /data/nginx/yqc/wap;
index index.html;
}
location /last {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/last/(.*) /test1/$1 last;
rewrite ^/test1/(.*) /test2/$1 last;
}
location /test1 {
root /data/nginx/yqc/wap;
index index.html;
}
location /test2 {
root /data/nginx/yqc/wap;
index index.html;
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 测试访问:
仅执行了 /last --> /test1 的重写,而未执行同一 location 中 /test1 --> /test2 的重写;
最终显示内容为 /test1 的内容;
[root@node105 ~]# curl -L http://wap.yqc.com/last/
test1 page
标记为 last 的新 URI 会多次匹配执行 rewrite 规则
- 编辑配置文件:
重写规则:break–>test1–>test2–>test3–>test4–>test5
[root@node106 ~]# vim /apps/nginx/conf.d/wap.yqc.com.conf
server {
listen 192.168.1.106:80;
server_name wap.yqc.com;
error_log /data/nginx/logs/wap-yqc-com_error.log notice;
rewrite_log on;
location / {
root /data/nginx/yqc/wap;
index index.html;
}
location /last {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/last/(.*) /test1/$1 last;
}
location /test1 {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/test1/(.*) /test2/$1 last;
}
location /test2 {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/test2/(.*) /test3/$1 last;
}
location /test3 {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/test3/(.*) /test4/$1 last;
}
location /test4 {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/test4/(.*) /test5/$1 last;
}
location /test5 {
root /data/nginx/yqc/wap;
index index.html;
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
会一直重写至 test5;
[root@node105 ~]# curl -L http://wap.yqc.com/last/
test5 page
- 查看 rewrite 日志:
2020/12/03 23:41:53 [notice] 22000#0: *15 "^/last/(.*)" matches "/last/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:41:53 [notice] 22000#0: *15 rewritten data: "/test1/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:41:53 [notice] 22000#0: *15 "^/test1/(.*)" matches "/test1/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:41:53 [notice] 22000#0: *15 rewritten data: "/test2/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:41:53 [notice] 22000#0: *15 "^/test2/(.*)" matches "/test2/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:41:53 [notice] 22000#0: *15 rewritten data: "/test3/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:41:53 [notice] 22000#0: *15 "^/test3/(.*)" matches "/test3/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:41:53 [notice] 22000#0: *15 rewritten data: "/test4/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:41:53 [notice] 22000#0: *15 "^/test4/(.*)" matches "/test4/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
2020/12/03 23:41:53 [notice] 22000#0: *15 rewritten data: "/test5/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yqc.com"
last 导致的重写循环
- 编辑配置文件:
形成 last<–>test1 的重写循环;
[root@node106 ~]# vim /apps/nginx/conf.d/wap.yqc.com.conf
server {
listen 192.168.1.106:80;
server_name wap.yqc.com;
error_log /data/nginx/logs/wap-yqc-com_error.log notice;
rewrite_log on;
location / {
root /data/nginx/yqc/wap;
index index.html;
}
location /last {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/last/(.*) /test1/$1 last;
}
location /test1 {
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/test1/(.*) /last/$1 last;
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
报 500 错误;
[root@node105 ~]# curl -L http://wap.yqc.com/last/
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
- 查看 rewrite 日志:
在第一次重写为 /test1 后,又执行了 10次重写操作,最后报 500 错误;
1 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/last/(.*)" matches "/last/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yq
c.com"
2 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/test1/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "w
ap.yqc.com"
3 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/test1/(.*)" matches "/test1/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.
yqc.com"
4 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/last/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wa
p.yqc.com"
5 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/last/(.*)" matches "/last/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yq
c.com"
6 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/test1/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "w
ap.yqc.com"
7 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/test1/(.*)" matches "/test1/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.
yqc.com"
8 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/last/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wa
p.yqc.com"
9 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/last/(.*)" matches "/last/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yq
c.com"
10 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/test1/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "w
ap.yqc.com"
11 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/test1/(.*)" matches "/test1/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.
yqc.com"
12 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/last/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wa
p.yqc.com"
13 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/last/(.*)" matches "/last/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yq
c.com"
14 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/test1/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "w
ap.yqc.com"
15 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/test1/(.*)" matches "/test1/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.
yqc.com"
16 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/last/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wa
p.yqc.com"
17 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/last/(.*)" matches "/last/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yq
c.com"
18 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/test1/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "w
ap.yqc.com"
19 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/test1/(.*)" matches "/test1/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.
yqc.com"
20 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/last/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wa
p.yqc.com"
21 2020/12/03 23:54:47 [notice] 22025#0: *18 "^/last/(.*)" matches "/last/", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "wap.yq
c.com"
22 2020/12/03 23:54:47 [notice] 22025#0: *18 rewritten data: "/test1/", args: "", client: 192.168.1.105, server: wap.yqc.com, request: "GET /last/ HTTP/1.1", host: "w
ap.yqc.com"
23 2020/12/03 23:54:47 [error] 22025#0: *18 rewrite or internal redirection cycle while processing "/test1/", client: 192.168.1.105, server: wap.yqc.com, request: "GE
T /last/ HTTP/1.1", host: "wap.yqc.com"
模拟用到 last 多次重写的场景
appv1 改版为 appv2,后又改版为 appv3,此时如果想让仍保留着 appv1 访问路径的用户,直接访问 appv3,通过连续两个标记 break 的 rewrite 规则即可实现,即 /appv1–> /appv2 --> /appv3,因为第一次 rewrite 后生成的新 URI(/appv2 )还能在经过一次 rewrite,从而重写为 appv3;
然而如果再进行了一次版本升级,想让用户通过 /appv1 访问到 /appv4,就要通过 last 来实现多次重写了;需要在追加 /appv3 --> /appv4 的重写规则时,将 /appv2 --> /appv3 的重写规则标记为 last;
P.S.
当然,这种应用场景基本遇不到,因为实际中只需添加 /appv1 --> /appv4 的 rewrite 规则即可,不需要连续重写;
顶多再分别单独添加 /appv2 --> /appv4、 /appv3 --> /appv4 的 rwrite 规则,即可将所有旧版本的 URL 重定向至新版本;
- 编辑配置文件:
[root@node106 ~]# cat /apps/nginx/conf.d/wap.yqc.com.conf
server {
listen 192.168.1.106:80;
server_name wap.yqc.com;
error_log /data/nginx/logs/wap-yqc-com_error.log notice;
rewrite_log on;
location / {
root /data/nginx/yqc/wap;
index index.html;
}
location /appv1{
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/appv1/(.*) /appv2/$1 break;
}
location /appv2{
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/appv2/(.*) /appv3/$1 last;
}
location /appv3{
root /data/nginx/yqc/wap;
index index.html;
rewrite ^/appv3/(.*) /appv4/$1 break;
}
location /appv4{
root /data/nginx/yqc/wap;
index index.html;
}
}
- 准备测试文件:
[root@node106 ~]# mkdir /data/nginx/yqc/wap/appv{1..4}
[root@node106 ~]# vim /data/nginx/yqc/wap/appv1/index.html
appv1
[root@node106 ~]# vim /data/nginx/yqc/wap/appv2/index.html
appv2
[root@node106 ~]# vim /data/nginx/yqc/wap/appv3/index.html
appv3
[root@node106 ~]# vim /data/nginx/yqc/wap/appv4/index.html
appv4
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试:
rwrite 规则如果都标记为 break,则重写至 /appv3 即停止;
将 /appv2 --> /appv3 的 rewrite 规则标记为 last,即可继续向后重写;
将 /appv3 --> /appv4 的rewrite 规则标记为 break,即可防止继续向后重写;
[root@node105 ~]# curl -L http://wap.yqc.com/appv1
appv4
4.6.5:rewrite 案例
rewrite 自动跳转 https
实现访问 http://www.yqc.com 时,自动跳转到 https://www.yqc.com;
- 编辑配置文件:
[root@node106 ~]# cat /apps/nginx/conf.d/www.yqc.com.conf
server {
listen 192.168.1.106:80;
listen 192.168.1.106:443 ssl;
server_name www.yqc.com;
ssl_certificate /apps/nginx/ssl/www.yqc.com.crt;
ssl_certificate_key /apps/nginx/ssl/www.yqc.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
error_page 500 502 503 504 404 /error.html;
access_log /data/nginx/logs/www-yqc-com_access_json.log format2;
error_log /data/nginx/logs/www-yqc-com_error.log notice;
gzip on;
gzip_comp_level 3;
gzip_min_length 1k;
gzip_types text/plain application/javascript application/x-javascript text/cssapplication/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
location / {
root /data/nginx/yqc/www;
index index.html;
if ( $scheme = http ) {
rewrite (.*) https://www.yqc.com permanent;
}
}
……
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试
rewrite 跳转默认页面
当访问的资源不存在时,自动跳转至默认页面;
- 编辑配置文件:
location / {
root /data/nginx/yqc/www;
index index.html;
if ( !-f $request_filename ) {
rewrite (.*) http://www.yqc.com/default.html;
}
}
- 检查配置文件并重载 nginx:
[root@node106 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@node106 ~]# systemctl reload nginx
- 访问测试: