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 指令:
<span style="color:#000000"><code class="language-py"><span style="color:#a71d5d">if</span> <span style="color:#969896">(</span>$http_user_agent <span style="color:#df5000">~</span> MSIE<span style="color:#969896">)</span> <span style="color:#969896">{</span>
rewrite <span style="color:#df5000">^</span><span style="color:#969896">(</span><span style="color:#969896">.</span><span style="color:#df5000">*</span><span style="color:#969896">)</span>$ <span style="color:#df5000">/</span>msie<span style="color:#df5000">/</span>$<span style="color:#c76b29">1</span> <span style="color:#a71d5d">break</span><span style="color:#969896">;</span>
<span style="color:#969896">}</span>
location <span style="color:#df5000">/</span>xiao<span style="color:#df5000">/</span> <span style="color:#969896">{</span>
<span style="color:#a71d5d">if</span> <span style="color:#969896">(</span>$http_user_agent <span style="color:#df5000">~</span> Mozilla<span style="color:#df5000">/</span><span style="color:#c76b29">5.0</span><span style="color:#969896">)</span> <span style="color:#969896">{</span> <span style="color:#969896">#如果是chrom浏览器</span>
rewrite <span style="color:#df5000">^</span><span style="color:#969896">(</span><span style="color:#969896">.</span><span style="color:#df5000">*</span><span style="color:#969896">)</span>$ http<span style="color:#969896">:</span><span style="color:#df5000">//</span>www<span style="color:#969896">.</span>example<span style="color:#969896">.</span>com<span style="color:#969896">;</span> <span style="color:#969896">#返回客户端302</span>
<span style="color:#969896">}</span>
<span style="color:#a71d5d">if</span> <span style="color:#969896">(</span>$http_user_agent <span style="color:#df5000">~</span> curl<span style="color:#969896">)</span> <span style="color:#969896">{</span> <span style="color:#969896"># 如果是curl 发起请求</span>
rewrite <span style="color:#df5000">^</span><span style="color:#df5000">/</span>xiao<span style="color:#df5000">/</span><span style="color:#969896">(</span><span style="color:#969896">.</span><span style="color:#df5000">*</span><span style="color:#969896">)</span>$ <span style="color:#df5000">/</span>xiao<span style="color:#df5000">/</span>$<span style="color:#c76b29">1.</span>txt <span style="color:#a71d5d">break</span><span style="color:#969896">;</span> <span style="color:#969896">#得到新的URI</span>
<span style="color:#969896">}</span>
<span style="color:#969896">}</span>
<span style="color:#a71d5d">if</span> <span style="color:#969896">(</span>$http_cookie <span style="color:#df5000">~</span><span style="color:#df5000">*</span> <span style="color:#df5000">"id=([^;]+)(?:;|$)"</span><span style="color:#969896">)</span> <span style="color:#969896">{</span>
<span style="color:#df5000">set</span> $<span style="color:#df5000">id</span> $<span style="color:#c76b29">1</span><span style="color:#969896">;</span> <span style="color:#969896">#提取了变量$1</span>
<span style="color:#969896">}</span>
<span style="color:#a71d5d">if</span> <span style="color:#969896">(</span>$request_method <span style="color:#df5000">=</span> POST<span style="color:#969896">)</span> <span style="color:#969896">{</span>
<span style="color:#a71d5d">return</span> <span style="color:#c76b29">405</span><span style="color:#969896">;</span> <span style="color:#969896">#可以限制Request Method</span>
<span style="color:#969896">}</span>
<span style="color:#a71d5d">if</span> <span style="color:#969896">(</span>$slow<span style="color:#969896">)</span> <span style="color:#969896">{</span>
limit_rate 10k<span style="color:#969896">;</span> <span style="color:#969896">#这个配置会加在location里面</span>
<span style="color:#969896">}</span>
<span style="color:#a71d5d">if</span> <span style="color:#969896">(</span>$invalid_referer<span style="color:#969896">)</span> <span style="color:#969896">{</span>
<span style="color:#a71d5d">return</span> <span style="color:#c76b29">403</span><span style="color:#969896">;</span>
<span style="color:#969896">}</span>
</code></span>
如果想更加深刻去了解rewrite的相关内容,可以参考博客:《一篇文章说透Nginx的rewrite模块》