nginx rewrite指令的深入理解

   nginx提供了强大的url rewrite功能。在nginx http模块的11个处理阶段中,有NGX_HTTP_SERVER_REWRITE_PHASE和NGX_HTTP_REWRITE_PHASE两个阶段来进行url rewrite的处理。而last、break、redirect、permenent几个关键字可以影响rewrite的行为,特别是last和break在概念上区别不是那么清晰,本来自己也对这个概念比较模糊,因此通过对nginx官方文档的理解,来学习和加深了解。

1. 指令格式

  首先来看一下rewrite指令的格式:

语法:	rewrite regex replacement [flag];
上下文:	server, location, if

  其中flag参数可以设置成以上四个关键字之一。

  另外nginx又单独提供了break和return两个指令,而不需要写在rewrite指令中,只不过这写指令都是有ngx_http_rewrite_module模块来定义的。

语法:	break;
上下文:	server, location, if
语法:	return code [text];
        return code URL;
        return URL;
上下文:	server, location, if

2. rewrite指令

  当一个请求的uri匹配到了配置的某个rewrite指令的正则表达式以后,uri将被修改为replacement替换规则定义的新的uri。rewrite指令的匹配顺序是按照在配置文件中定义的先后顺序的执行的。而且根据rewrite指令设置的flag标记可以停止后续的进一步的处理工作。如果replacement字符串是http://或者https://或者$scheme开头的,那么nginx将发送http redirect响应给客户端并且停止后续的处理。

  • last标记:
      停止当前这组url rewrite指令,并让nginx按照当前rewrite后的uri开始查找新的location。

  • break标记:
      停止当前这组url rewrite指令,如果当前的rewrite指令是在location块里面,那么和last不同,接下去的处理将局限在当前的location之内。

  • redirect标记:
      给客户端响应一个302重定向,重定向地址为当前url rewrite后的uri地址,这个标记是在replacement字符串不是以http://或者https://或者$scheme://开头的情况的时候进行设置的。

  • permenent标记:
      给客户端响应一个301重定向,重定向地址为当前url rewrite后的uri地址,这个标记是在replacement字符串不是以http://或者https://或者$scheme://开头的情况的时候进行设置的。

  • 没有设置标记:
      nginx将在本组rewrite指令中(包括break和last指令)按顺序从头执行一遍,如果rewrite匹配了,那么当前重写的uri将作为新的uri输入到后续的rewrite中进行匹配。

  用nginx官方文档中的例子:

server {
    ...
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  last;
    return  403;
    ...
}

  以上rewrite指令是放在server块中的,而不是location块,那么会将类似 /download/abc/media/test.xx的uri改写成 /download/mp3/test.mp3,然后会执行location查找匹配定位由哪个location来处理客户端的请求,因为这里last标记的定义就是这样子的。
  那么如果把以上rewrite指令放到location里面,还是用last标记,那么会产生nginx超过10次rewrite循环,从而响应500的错误。在location块中,应该改成break标记,一旦匹配完成url rewrite后,就限制在当前location中处理客户端的请求,而不再重新查找location了。

location /download/ {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  break;
    return  403;
}

  因为nginx的NGX_HTTP_SERVER_REWRITE_PHASE阶段是在location查找之前发生的,那么在server块中的last和break标记是没有什么差异的,最终还是会进入location查找。last和break的差异主要是体现在location块中的rewrite指令。

3. break指令

  break指令的含义和rewrite指令中的break标记的含义是相同的,它将停止当前这组ngx_http_rewrite_module指令的执行。如果break是在location块里面的,那么nginx将限制请求的处理仍然限制在当前的location中执行。

4. return指令

  执行到这个指令的时候,nginx直接返回一个http状态码和状态信息,或者如果是301/302/307/308状态码,则可以指定一个重定向的url。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农心语

您的鼓励是我写作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值