nginx的脚本引擎rewrite
Posted 你的币掉了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx的脚本引擎rewrite相关的知识,希望对你有一定的参考价值。
其实rewrite指令和上一篇说的if/set/return/break之类的没多大差别,但是rewrite用起来相对复杂,我就把他单独放到了这里。想要弄懂nginx的脚本引擎需要先明白处理request的十一个处理阶段,不懂的话先去搜一下看看,网上很多。先说一下rewrite的用法吧。
rewrite regex replacement [flag];
regex:用来匹配uri的正则表达式。
replacement:匹配成功后用这个字段替换请求的uri。
上面这两个没什么可说的,简单明白,看一下flag,flag可以取的值如下:
last:当前指令执行完之后不在执行之后的指令,如果是在location块里这个请求会重新回到NGX_HTTP_FIND_CONFIG_PHASE阶段用新的uri寻找新location。
break:当前指令执行完之后不在执行之后的指令。
redirect:返回302重定向。
permanent 返回301重定向。
redirect和permanent比较简单,就不用说了,主要是区分last和break,这两个指令用在server块里没什么区别,但是用在location块里就要注意了,下面这个配置是我把官方文档上的例子拿过来改的。
location /download/ { rewrite ^(/download/)(.*)..*$ $1/mp3/$2.mp3 break; rewrite ^(/download/)(.*)..*$ $1/mp3/$2.ra break; return 403; }
如果把break换成last,并且匹配上了这条指令修改uri之后,请求会重新回到NGX_HTTP_FIND_CONFIG_PHASE阶段,因为uri的前缀没变会继续匹配到这个location,再执行rewrite,造成死循环,最终返回500错误。
我觉得官方文档上的例子并不会造成500错误,是我理解的不对还是他举的例子不对?传送门http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite
这几个标志都会执行如下的代码,结束当前的脚本。
if (last) { code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t), ®ex); if (code == NULL) { return NGX_CONF_ERROR; } *code = NULL; }
不同的是break的情况,break会额外执行如下的代码
if (code->uri) { r->internal = 1; r->valid_unparsed_uri = 0; if (code->break_cycle) { r->valid_location = 0; r->uri_changed = 0; } else { r->uri_changed = 1; } }
把r->uri_changed置位,到了NGX_HTTP_POST_REWRITE_PHASE会检查这个标志,如果不为0就会跳回NGX_HTTP_FIND_CONFIG_PHASE阶段,这就是break标志和last标志的不同。
以上是关于nginx的脚本引擎rewrite的主要内容,如果未能解决你的问题,请参考以下文章
nginx 隐藏index.php 并开启rewrite日志调试