1.rewrite介绍
Nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。
关于rewrite:
- rewrite只能放在server{},location{},if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用。
- rewrite主要的功能就是实现URL的重写,Nginx的Rewrite规则采用Pcre,perl兼容正则表达式的语法规则匹配,如果需要Nginx的Rewrite功能,在编译Nginx之前,需要编译安装PCRE库。
- 通过Rewrite规则,可以实现规范的URL、根据变量来做URL转向及选择配置。
2.rewrite指令的工作原理
rewrite模块的指令有break, if, return, rewrite, set等。rewrite指令所执行的顺序如下:
- 首先在server上下文中依照顺序执行rewrite模块指令;
- 如果server中行了rewrite重写,那么以新URI发起内部跳转,直接匹配location,不会再执行server里的rewrite指令,然后
----
新URI直接匹配location----
如果匹配上某个location,那么其中的rewrite模块指令同样依照顺序执行----
如果再次导致URI的rewrite,那么再一次进行内部跳转去匹配location,但跳转的总次数不能超过10次
3.rewrite全局变量
nginx的rewrite规则就是使用正则匹配请求的url,然后根据定义的规则进行重写和改变,需ngx_http_rewrite_module
模块来支持url重写功能,该模块是标准模块,默认已经安装。
变量 | 含义 |
$args | 这个变量等于请求行中的参数,同$query_string |
$content length | 请求头中的Content-length字段。 |
$content_type | 请求头中的Content-Type字段。 |
$document_root | 当前请求在root指令中指定的值。 |
$host | 请求主机头字段,否则为服务器名称。 |
$http_user_agent | 客户端agent信息 |
$http_cookie | 客户端cookie信息 |
$limit_rate | 这个变量可以限制连接速率。 |
$request_method | 客户端请求的动作,通常为GET或POST。 |
$remote_addr | 客户端的IP地址。 |
$remote_port | 客户端的端口。 |
$remote_user | 已经经过Auth Basic Module验证的用户名。 |
$request_filename | 当前请求的文件路径,由root或alias指令与URI请求生成。 |
$scheme | HTTP方法(如http,https)。 |
$server_protocol | 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 |
$server_addr | 服务器地址,在完成一次系统调用后可以确定这个值。 |
$server_name | 服务器名称。 |
$server_port | 请求到达服务器的端口号。 |
$request_uri | 包含请求参数的原始URI,不包含主机名,如”/foo/bar.php?arg=baz”。 |
$uri | 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。 |
$document_uri | 与$uri相同。 |
4.案例
下面来举个例子,使用if 指令:
if ($http_user_agent ~ MSIE) { rewrite ^(.*)$ /msie/$1 break; } location /xiao/ { if ($http_user_agent ~ Mozilla/5.0) { #如果是chrom浏览器 rewrite ^(.*)$ http://www.example.com; #返回客户端302 } if ($http_user_agent ~ curl) { # 如果是curl 发起请求 rewrite ^/xiao/(.*)$ /xiao/$1.txt break; #得到新的URI } } if ($http_cookie ~* "id=([^;]+)(?:;|$)") { set $id $1; #提取了变量$1 } if ($request_method = POST) { return 405; #可以限制Request Method } if ($slow) { limit_rate 10k; #这个配置会加在location里面 } if ($invalid_referer) { return 403; }
如果想更加深刻去了解rewrite的相关内容,可以参考博客:《一篇文章说透Nginx的rewrite模块》
总结