Nginx 服务器利用 ngx_http_rewrite_module 模块解析和处理 rewrite 请求。
此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装 PCRE 库,rewrite 是 Nginx 服务器的重要功能之 一,用于实现 URL 的重写,URL 的重写是非常有用的功能,例如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问,还可以在一定程度上提高网站的安全性。

1. 模块指令

1.1 if 指令

用于条件匹配判断,并根据条件判断结果选择不同的 Nginx 配置,可以配置在 server 或 location 域中,if 语法仅能使用 if 做单次判断,不支持使用 if else 或者 if elif 这样的多重判断。

  1. if (条件判断) {
  2. action
  3. }
  4. =: 比较变量和字符串是否相等
  5. !: 判断结果取反
  6. !=: 比较变量和字符串是否不相等
  7. ~: 区分大小写字符,可以通过正则表达式匹配
  8. ~*: 不区分大小写字符,可以通过正则表达式匹配
  9. -f 判断请求的文件是否存在
  10. -d 判断请求的目录是否存在
  11. -x 判断文件是否可执行
  12. -e 判断请求的文件或目录是否存在(包括文件,目录,软链接)
  13. 范例:
  14. location /main {
  15. index index.html;
  16. default_type text/html;
  17. if ( $scheme = http ){
  18. echo "if-----> $scheme";
  19. }
  20. if ( $scheme = https ){
  21. echo "if ----> $scheme";
  22. }
  23. #if (-f $request_filename) {
  24. # echo "$request_filename is exist";
  25. #}
  26. if (!-e $request_filename) {
  27. echo "$request_filename is not exist";
  28. #return 409;
  29. }
  30. }

1.2 set 指令

用于自定义变量,变量可以调用 Nginx 内置变量赋值给key,定义格式为 set $key value,value 可以是 text 或 variables 或两者的组合。
注意:set 指令创建的变量是 Nginx 配置全局域可用的,但变量值只有在该变量赋值操作的 HTTP 处理流程中可用。

  1. location /main {
  2. root /data/nginx/html/pc;
  3. index index.html;
  4. default_type text/html;
  5. set $name wuvikr;
  6. echo $name;
  7. set $my_port $server_port;
  8. echo $my_port;
  9. }

1.3 break 指令

用于中断当前相同作用域 location 中的其他 Nginx 配置,与该指令处于同一作用域的 Nginx 配置中,位于它前面的配置生效,位于后面的ngx_http_rewrite_module 模块中指令就不再执行,Nginx 服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在 server,location 和 if 域中使用。
注意:如果 break 指令在 location 块中,后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行。

  1. location /main {
  2. root /data/nginx/html/pc;
  3. index index.html;
  4. default_type text/html;
  5. set $name magedu;
  6. echo $name;
  7. break; #location块中break后面指令还会执行
  8. set $my_port $server_port;
  9. }

1.4 return 指令

用于完成对请求的处理,并直接向客户端返回响应状态码,比如可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return 可以在 server、if 和 location 域中进行配置。

  1. return code; # 返回给客户端指定的 HTTP 状态码
  2. return code [text]; # 返回给客户端的状态码及响应报文的实体内容,因为有文本内容,code 不可以是 30X,可以调用变量.
  3. return code URL; # 如果该 URL 不是具有完整 scheme 标识的 URL,该 URL 会被添加到当前 URL 之后。
  4. return URL; # 此时 code 默认是 302,URL 必须是有完整 scheme 标识的 URL。
  5. server {
  6. listen 80;
  7. server_name www.wuvikr.top;
  8. location / {
  9. root /data/nginx/html/pc;
  10. default_type text/html;
  11. index index.html;
  12. if ( $scheme = http ){
  13. #return 666;
  14. #return 666 "not allow http";
  15. #return 302 www.wuvikr.top/test; # 错误配置,浏览器会去重新访问 www.wuvikr.top/www.wuvikr.top/test。
  16. #return 302 test; # 正确配置,浏览器会去重新访问 www.wuvikr.top/test。
  17. #return 302 http://www.wuvikr.top/test; # 正确配置,浏览器会去重新访问 www.wuvikr.top/test。
  18. #return http://www.wuvikr.top/test; # 正确配置,浏览器会去重新访问 www.wuvikr.top/test。
  19. return test; # 错误配置,不写code 时,URL 必须是有完整 scheme 标识的 URL。
  20. echo "if-----> $scheme"; # return 后面的将不再执行
  21. }
  22. if ( $scheme = https ){
  23. echo "if ----> $scheme";
  24. }
  25. }
  26. }

1.5 rewrite_log 指令

用于开启 rewrite 相关执行结果以 notice 级别日志记录到 error_log 日志文件当中,可以配置在 http、server、location 或 if 中。

  1. location /main {
  2. rewrite_log on;
  3. error_log log/main-error.log notice;
  4. }

1.5 rewrite 指令

对用户的 URI 用正则表达式的方式进行重写,并跳转到新的 URI。可以配置在 server、location、if 中。
语法格式如下:
rewrite regex replacement [flag];

  • regex 是 PCRE 语法格式的正则表达式;
  • replacement 是重写 URI 的改写规则,注意:如果替换后的 URI 是以 **http://****https://** 等 scheme 协议开头时,则 Nginx 重写该语句后会停止执行后续任务,直接以 302 重定向将 URI 返回给客户端。
  • flag 是执行该条重写指令后的操作控制符,操作控制符有以下 4 种:

    • last:执行完当前重写规则跳转到新的 URI 后会优先跳出去匹配 location ,而不是继续向下匹配。
    • break:执行完当前重写规则跳转到新的 URI 后不再执行后续的 rewrite 模块的其他指令。
    • redirect:返回 302 响应状态码的临时重定向,返回重定向 URI 内容,但用户浏览器网址仍然是请求时的 URI。
    • permanent:返回 301 响应状态码的永久重定向,返回重定向 URI 内容,用户浏览器网址是重定向后的 URI。
    • 没有 flag:没有 flag 的情况下,rewrite 匹配完成后会继续在 location 中向下执行,直到 rewrite 模块指令全部执行完成。

      1.5.1 案例一:HTTP 重写到 HTTPS

  • 方式一:

    1. server {
    2. server_name www.wuvikr.com;
    3. listen 80;
    4. listen 443 ssl;
    5. ssl_certificate /apps/nginx/certs/www.wuvikr.com.pem;
    6. ssl_certificate_key /apps/nginx/certs/www.wuvikr.com.key;
    7. ssl_session_cache shared:sslcache:20m;
    8. ssl_session_timeout 10m;
    9. # 针对全站跳转
    10. location / {
    11. root /data/nginx/html/pc;
    12. index index.html;
    13. if ($scheme = http ){ # 如果没有加条件判断,可能会导致死循环
    14. rewrite / https://$host redirect;
    15. rewrite / https://$host redirect;
    16. }
    17. }
    18. # 针对特定的URL进行跳转https
    19. location /login {
    20. if ($scheme = http ){
    21. rewrite / https://$host/login redirect;
    22. }
    23. }
    24. }
  • 方式二: ```bash server { server_name www.wuvikr.com; listen 443 ssl; ssl_certificate /apps/nginx/certs/www.wuvikr.com.pem; ssl_certificate_key /apps/nginx/certs/www.wuvikr.com.key; ssl_session_cache shared:sslcache:20m; ssl_session_timeout 10m; … }

server { server_name www.wuvikr.com; listen 80; rewrite ^(.*)$ https://${host}$1? permanent; } ```

1.5.2 案例二: