• Nginx使用的是ngx_http_rewrite_module模块来解析和处理Rewrite功能的相关配置。
  • Rewrite常用全局变量:
变量 说明
$args 变量中存放了请求URL中的请求参数。比如http://192.168.200.133/server?arg1=value1&args2=value2中的"arg1=value1&arg2=value2",功能和$query_string一样
$http_user_agent 变量存储的是用户访问服务的代理信息(如果通过浏览器访问,记录的是浏览器的相关版本信息)
$host 变量存储的是访问服务器的server_name值
$document_uri 变量存储的是当前访问地址的URI。比如http://192.168.200.133/server?id=10&name=zhangsan中的"/server",功能和$uri一样
$document_root 变量存储的是当前请求对应location的root值,如果未设置,默认指向Nginx自带html目录所在位置
$content_length 变量存储的是请求头中的Content-Length的值
$content_type 变量存储的是请求头中的Content-Type的值
$http_cookie 变量存储的是客户端的cookie信息,可以通过add_header Set-Cookie ‘cookieName=cookieValue’来添加cookie数据
$limit_rate 变量中存储的是Nginx服务器对网络连接速率的限制,也就是Nginx配置中对limit_rate指令设置的值,默认是0,不限制。
$remote_addr 变量中存储的是客户端的IP地址
$remote_port 变量中存储了客户端与服务端建立连接的端口号
$remote_user 变量中存储了客户端的用户名,需要有认证模块才能获取
$scheme 变量中存储了访问协议
$server_addr 变量中存储了服务端的地址
$server_name 变量中存储了客户端请求到达的服务器的名称
$server_port 变量中存储了客户端请求到达服务器的端口号
$server_protocol 变量中存储了客户端请求协议的版本,比如"HTTP/1.1"
$request_body_file 变量中存储了发给后端服务器的本地文件资源的名称
$request_method 变量中存储了客户端的请求方式,比如"GET",“POST"等
$request_filename 变量中存储了当前请求的资源文件的路径名
$request_uri 变量中存储了当前请求的URI,并且携带请求参数,比如http://192.168.200.133/server?id=10&name=zhangsan中的”/server?id=10&name=zhangsan"

相关指令

set指令

  1. 设置一个新的变量。
    • variable:变量的名称,该变量名称要用"$“作为变量的第一个字符,且不要与Nginx服务器预设的全局变量同名。
    • value:变量的值,可以是字符串、其他变量或者变量的组合等。
语法 set $variable value;
默认值
位置 server、location、if

if指令

  1. 用来支持条件判断,并根据条件判断结果选择不同的Nginx配置。
语法 if (condition){…}
默认值
位置 server、location
# 1) $param 为空字符串或"0",if都判断为false
if ($param){}

# 2) "="和"!="比较变量和字符串是否相等,满足条件为true,注意=前后空格
if ($request_method = POST){}

# 3) 正则表达式对变量进行匹配,匹配成功返回true,否则返回false。
#   - "~"代表匹配正则表达式过程中区分大小写
#   - "~\*"代表匹配正则表达式过程中不区分大小写
#   - "!~"和"!~\*"刚好和上面取相反值,如果匹配上返回false,匹配不上返回true
# 正则表达式字符串一般不需要加引号,但是如果字符串中包含"}"或者是";"等字符时,就需要把引号加上。
if ($http_user_agent ~ MSIE){} # $http_user_agent的值中是否包含MSIE字符串,如果包含返回true

# 4)  判断请求的文件是否存在使用"-f"和"!-f"
if (-f $request_filename){} # 判断请求的文件是否存在
if (!-f $request_filename){} # 判断请求的文件是否不存在

# 5) 判断请求的目录是否存在使用"-d"和"!-d"
if (-d $request_dir){}

# 6) 判断请求的目录或者文件是否存在使用"-e"和"!-e"
# 7) 判断请求的文件是否可执行使用"-x"和"!-x"

break指令

  1. 用于中断当前相同作用域中的其他Nginx配置。
  2. 与该指令处于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置无效。
  3. 并且break还有另外一个功能就是终止当前的匹配并把当前的URI在本location进行重定向访问处理。
语法 break;
默认值
位置 server、location、if
location /testbreak{
    default_type text/plain;
    set $username TOM;
    if ($args){
        Set $username JERRY;
        break;
        set $username ROSE;
    }
    add_header username $username;
    return 200 $username;
}

return指令

  1. 用于完成对请求的处理,直接向客户端返回。在return后的所有Nginx配置都是无效的。
    • code:为返回给客户端的HTTP状态代理。可以返回的状态代码为0~999的任意HTTP状态代理。
    • text:为返回给客户端的响应体内容,支持变量的使用。
    • URL:为返回给客户端的URL地址。
语法 return code [text]; | return code URL; | return URL;
默认值
位置 server、location、if
location /testreturn {
    return 200 success;
}

location /testreturn {
    return https://www.baidu.com; # 302重定向到百度
}

location /testreturn {
    return 302 https://www.baidu.com;
}

location /testreturn {
    return 302 www.baidu.com; # 不允许这么写
}

rewrite指令

  1. 通过正则表达式的使用来改变URI。可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理。
语法 rewrite regex replacement [flag];
默认值
位置 server、location、if
  1. regex参数:用来匹配URI的正则表达式。
  2. replacement参数:匹配成功后,用于替换URI中被截取内容的字符串。如果该字符串是以"http://“或者"https://“开头的,则不会继续向下对URI进行其他处理,而是直接返回重写后的URI给客户端。
location rewrite {
    rewrite ^/rewrite/url\w*$ https://www.baidu.com;
    rewrite ^/rewrite/(test)\w*$ /$1;
    rewrite ^/rewrite/(demo)\w*$ /$1;
}
location /test{
    default_type text/plain;
    return 200 test_success;
}
location /demo{
    default_type text/plain;
    return 200 demo_success;
}
  1. flag:用来设置rewrite对URI的处理行为:

    last、break、redirect、permanent
    1. last:终止继续在本location块中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用各location块进行处理。该标志将重写后的URI重写在server块中执行,为重写后的URI提供了转入到其他location块的机会。
    location rewrite {
      rewrite ^/rewrite/(test)\w*$ /$1 last;
      rewrite ^/rewrite/(demo)\w*$ /$1 last;
    }
    
    # http://localhost/rewrite/testabc 能命中这
    location /test{
      default_type text/plain;
      return 200 test_success;
    }
    location /demo{
      default_type text/plain;
      return 200 demo_success;
    }
    
    1. break:将此处重写的URI作为一个新的URI,在本块中继续进行处理。该标志将重写后的地址在当前的location块中执行,不会将新的URI转向其他的location块。
    # http://localhost/rewrite/demoabc 报错
    location rewrite {
      #/test   /usr/local/nginx/html/test/index.html
      rewrite ^/rewrite/(test)\w*$ /$1 break;
      rewrite ^/rewrite/(demo)\w*$ /$1 break;
    }
    location /test{
      default_type text/plain;
      return 200 test_success;
    }
    location /demo{
      default_type text/plain;
      return 200 demo_success;
    }
    
    1. redirect:将重写后的URI返回给客户端,状态码为302,指明是临时重定向URI,主要用在replacement变量不是以"http://“或者"https://“开头的情况。
    # http://localhost/rewrite/testabc`请求会被临时重定向,浏览器地址也会发生改变
    location rewrite {
      rewrite ^/rewrite/(test)\w*$ /$1 redirect;
      rewrite ^/rewrite/(demo)\w*$ /$1 redirect;
    }
    location /test{
      default_type text/plain;
      return 200 test_success;
    }
    location /demo{
      default_type text/plain;
      return 200 demo_success;
    }
    
    1. permanent:将重写后的URI返回给客户端,状态码为301,指明是永久重定向URI,主要用在replacement变量不是以"http://“或者"https://“开头的情况。
    # http://localhost/rewrite/testabc`请求会被永久重定向,浏览器地址也会发生改变
    location rewrite {
      rewrite ^/rewrite/(test)\w*$ /$1 permanent;
      rewrite ^/rewrite/(demo)\w*$ /$1 permanent;
    }
    location /test{
      default_type text/plain;
      return 200 test_success;
    }
    location /demo{
      default_type text/plain;
      return 200 demo_success;
    }
    

rewrite_log指令

  1. 该指令配置是否开启URL重写日志的输出功能。
语法 rewrite_log on|off;
默认值 rewrite_log off;
位置 http、server、location、if
  1. 开启后,URL重写的相关日志将以notice级别输出到error_log指令配置的日志文件汇总。
rewrite_log on;
error_log  logs/error.log notice;

域名跳转

  1. www.it.cn、www.it.vip 跳转到 www.ix.com
server {
    listen 80;
    server_name www.it.cn www.it.vip;
    # (.*)捕获请求的URI和相关参数
    rewrite ^(.*) http://www.ix.com$1;
}

独立域名

  1. 一个完整的项目包含多个模块,比如购物网站有商品搜索模块、商品详情模块和购物车模块等,那么我们如何为每一个模块设置独立的域名。
http://search.xxss.com:81  访问商品搜索模块
http://item.xxss.com:82	  访问商品详情模块
http://cart.xxss.com:83	  访问商品购物车模块
server{
    listen 81;
    server_name search.xxss.com;
    rewrite ^(.*) http://www.xxss.cn/search$1;
}
server{
    listen 82;
    server_name item.xxss.com;
    rewrite ^(.*) http://www.xxss.cn/item$1;
}
server{
    listen 83;
    server_name cart.xxss.com;
    rewrite ^(.*) http://www.xxss.cn/cart$1;
}

防盗链

  1. 当出现防盗链的情况,我们可以使用rewrite将请求转发到自定义的一张图片和页面,给用户比较好的提示信息。
location /images {
    root html;
    valid_referers none blocked www.baidu.com;

    if ($invalid_referer){
        #return 403;
        rewrite ^/ /images/forbidden.png break;
    }
}