四: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
  • 测试访问存在的资源:

nginx config中的 判断 nginx 判断文件是否存在_nginx

  • 测试访问不存在的资源:

nginx config中的 判断 nginx 判断文件是否存在_nginx config中的 判断_02

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

nginx config中的 判断 nginx 判断文件是否存在_nginx config中的 判断_03

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
  • 访问测试:

nginx config中的 判断 nginx 判断文件是否存在_配置文件_04

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 的值为空;

nginx config中的 判断 nginx 判断文件是否存在_nginx_05

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;

nginx config中的 判断 nginx 判断文件是否存在_nginx_06

  • 访问不存在的资源:

echo 指令正常显示;

nginx config中的 判断 nginx 判断文件是否存在_nginx config中的 判断_07

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 下的其它资源,不受影响;

nginx config中的 判断 nginx 判断文件是否存在_html_08

nginx config中的 判断 nginx 判断文件是否存在_nginx config中的 判断_09

nginx config中的 判断 nginx 判断文件是否存在_nginx_10

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;

nginx config中的 判断 nginx 判断文件是否存在_html_11

nginx config中的 判断 nginx 判断文件是否存在_html_12

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
[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
  • 访问并查看响应状态码:

nginx config中的 判断 nginx 判断文件是否存在_nginx_13

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
  • 访问并查看响应状态码:

nginx config中的 判断 nginx 判断文件是否存在_配置文件_14

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
  • 访问测试

nginx config中的 判断 nginx 判断文件是否存在_配置文件_15

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
  • 访问测试:

nginx config中的 判断 nginx 判断文件是否存在_nginx_16