nginx中rewrite配置规则

nginx中rewrite模块,有如下一些指令:

set   if return break rewrite ...

另外还有一些可用的全局变量,如:

$content_length $host $request_uri ....

通过这些可灵活配置rewrite功能,具体可以参考

http://zhumeng8337797.blog.163.com/blog/static/1007689142011815642384/

http://blog.csdn.net/xiao_jun_0820/article/details/9397011

有很多典型的rewrite例子。


其中最核心的是rewrite指令,也是最容易混淆的,具体看一下。

syntax: rewrite regex replacement [flag];
default:
context: serverlocationif

If the specified regular expression matches a request URI, URI is changed as specified in the replacement string. The rewritedirectives are executed sequentially in order of their appearance in the configuration file. It is possible to terminate further processing of the directives using flags. If a replacement string starts with “http://” or “https://”, the processing stops and the redirect is returned to a client.

An optional flag parameter can be one of:

last
stops processing the current set of  ngx_http_rewrite_module directives and starts a search for a new location matching the changed URI;
break
stops processing the current set of  ngx_http_rewrite_module directives as with the  break directive;
redirect
returns a temporary redirect with the 302 code; used if a replacement string does not start with “ http://” or “ https://”;
permanent
returns a permanent redirect with the 301 code.
其格式很简单,意义也比较明确,要注意的就是4种不同flag,其中redirect、permanent分别对应的302、301重定向。在早期的nginx版本中,return指令只能接一个code,所以不能返回301、302(因为他们还需要新的uri),因此在rewrite中用这两个flag来完成。如今新版本nginx中,return已可同时接code、uri,不过这两个flag还是保留下来了。

另两个flag:last、break容易搞错,首先需要了解nginx中core_run_phases的概念:

----------->server_rewrite--------->find_config------------>location_rewrite----------->post_rewrite------------>

有两个阶段的rewrite,分别来看。


server_rewrite一般用于全局性的rewrite,位于server{ }块中,且只执行一次

server {
		listen	80;	

		set $use_rewrite	1;

		if ($use_rewrite) {
			rewrite	^/(.*\.(png|jpg|gif))$	/static/$1	break|last;
			rewrite ^/static/(.+)$ 		/$1 		break|last;
			return 400;
		}
		location /luafile { ... }
}

这时break、last没有什么区别,就是终止当前rewrite_phase(后面的rewrite指令都不会执行),然后进入find_config_phase。要注意的是uri要匹配到rewrite指令中的正则表达式,该flag才会发挥作用。若请求为 "/luafile",则会执行到最后的return 400。


location_rewrite阶段要特别注意这两个flag,因为他们可能会会多次执行:

                                                                                v--------last(且循环次数<10)--------------------^

----------->server_rewrite--------->find_config------------>location_rewrite----------->post_rewrite-------break------->

上图已经很清楚的表明了他们之间的区别,下面举几个典型的例子。

		location  ^~ /static/ {
			root webroot;
		}

		location ~ \.(png|jpg|css|gif|js)$ {
			root webroot/res;
			if ($as_static) {
				rewrite	^/(.*\.(png|jpg|gif))$	/static/$1	break|last;
				return 400;
			}
		}
和之前一样,他们都起到终止当前rewrite_phase,不会执行到下面的return 400,。

但这里应该用last,重新find_config,匹配到location ^~ /static/ { ... },从而在root=webroot下找文件/static/xx.jpg;

若是用break,uri被改为了/static/xx.jpg,然后直接往后进入到content_phase,但此时的root=webroot/res/,那么整个路径为webroot/res/static/xx.jpg,这里是找不到文件的。


		location  ^~ /static/ {
			root webroot;
			rewrite	^/static/(.+)\.html$	/static/$1.jpg	break;
		}
这里应该用break,直接就在root=webroot下找/static/xx.jpg。如果改用last,重新find_config,会定位到其他location。


		location  ^~ /static/ {
			root webroot;
			rewrite	^/static/(.+)/(.+)$	/static/$1$1/$2	last;
		}
这个例子用的last标志,若请求为/static/mp3/one.mp3,则会循环执行 find_config---->location_rewrite,最多循环10次,还是没有break指令跳出location_rewrite phase,则会返回500(服务器内部错误)。

但若请求为/static/one.mp3,对于老版本的nginx,可能还是循环10后返回500(正如网上一些帖子说的),我用的1.2的版本,好像没有这个问题,因为uri并不匹配rewrite指令的正则式,所以uri并不会被改变,也就是说rewrite指令并没有起作用,那么当然不用重新fing_config了,会直接往下执行。


另外,还有一些关于域名重定向,query语句等,可以参考网上其他的帖子。




你可能感兴趣的:(nginx)