在使用nginx重写(即rewrite)机制时,大家一般会用到last和break,关于这两个指令的作用,网友问的挺多,网上的讨论也挺多,这里做个总结:
网友的给力解释:
last:
重新将rewrite后的地址在server标签中执行
break:
将rewrite后的地址在当前location标签中执行
nginx官方解释:
last:
stops processing the current set of ngx_http_rewrite_module
directives followed by a search for a new location matching
the changed URI;
break:
stops processing the current set of ngx_http_rewrite_module
directives;
其实网友的解释更容易懂一些,nginx官方的解释则是从偏重实现的角度来说的,说到这里,许多人可能还是对这两个指令的使用不是太自信,感觉心里没底,说实话我当初也是这么感觉的,那么就让我们打破沙锅问到底,看看代码到底是怎么实现的,毕竟,”代码面前无秘密“。
为了方便我们的讨论我们做出以下的假想配置:
- location /download/ {
- rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
- rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
- return 403;
- }
在分析之前,看官们需要熟悉nginx各个phase handler的处理,以及nginx变量的基本原理,不熟悉的同学看起来可能会有点难度,那么这里给出了相关的连接,方面不熟悉的同学学习。前两个是关于handler的,后一个是关于变量的:
现在进入正题:
在函数ngx_http_rewrite中:
- if (cf->args->nelts == 4) {
- if (ngx_strcmp(value[3].data, "last") == 0) {
- last = 1;
-
- } else if (ngx_strcmp(value[3].data, "break") == 0) {
- regex->break_cycle = 1;
- last = 1;
-
- }
- ...
- }
重点在于last = 1的处理,在稍后:
- if (last) {
- code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t), ®ex);
- if (code == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *code = NULL;
- }
lcf->codes是个数组里面保存了当前各个rewrite执行对应的相关操作(即各种handler)和数据,这里的操作是在这个数组中添加一个null,这个null的意义重大,在rewrite实际执行时,如ngx_http_rewrite_handler的调用,就会对事先放置在这个数组里的handler进行处理:
- e->ip = rlcf->codes->elts;
- ...
-
-
-
- while (*(uintptr_t *) e->ip) {
- code = *(ngx_http_script_code_pt *) e->ip;
- code(e);
- }
比如在开始的配置里面,我们写成:
- location /download/ {
- rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3;
- rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra;
- return 403;
- }
即不写last和break,那么流程就是依次执行这些rewrite,直到最后以403结束这次请求,这种情况下codes数组中的handler都得以执行了,而由于
last和break的出现,处理可能在中间的某个位置终止,后面的rewrite,就不会执行了。
在rewrite阶段的处理结束之后,则会转到find config阶段,这个阶段本来是在rewrite阶段之前的,这样的过程也刻画了rewrite的基本流程,url经过rewrite阶段被改变了,而一个请求处理的关键步骤之一就是要确定对应的server conf和location conf,而find config的作用恰恰就是如此,重写之后url可以看做是一个新的请求,所以这些关键步骤需要走一遍就是理所当然了。
另一个问题,在ngx_http_rewrite函数中break_cycle的设置,也就是在出现break的时候,这个变量会被置1,而这个变量的设置,最终会导致r->uri_changed被置为0,那么它的直接影响可以在下面的地方看到:
-
- ngx_http_core_post_rewrite_phase
- {
-
-
-
-
- if (!r->uri_changed) {
- r->phase_handler++;
- return NGX_AGAIN;
- }
- ...
- }
关于r->uri_changed被置为0的操作,可以参考:
ngx_http_script_regex_start_code和ngx_http_script_break_code
所以这里概括下:
last其实就相当于一个新的url,对nginx进行了一次请求,需要走一遍大多数的处理过程,最重要的是会做一次find config,提供了一个可以转到其他location的配置中处理的机会,而break则是在一个请求处理过程中将原来的url(包括uri和args)改写之后,在继续进行后面的处理,这个重写之后的请求始终都是在同一个location中处理。
分享到:
相关推荐
在Nginx中,Rewrite模块是实现URL重写的重要工具,它允许我们根据预定义的规则对请求的URL进行转换,从而实现动态URL到静态URL的映射、隐藏真实路径、实现URL路由等目的。这篇文档将深入解析Nginx中Rewrite模块的...
本文将深入探讨Nginx的Rewrite规则,通过实例来展示其在实际场景中的应用,帮助读者更好地理解和掌握这一关键技能。 #### 一、Rewrite规则的基本语法 Rewrite规则主要通过`rewrite`指令实现,其基本语法结构如下:...
Nginx的rewrite模块允许我们根据特定的条件重写请求的URI,这在实现URL路由、隐藏真实路径、SEO优化等方面非常有用。它的语法结构通常为: ```nginx rewrite <regex> <replacement> ; ``` 其中,`<regex>`是正则...
Nginx 中的 rewrite 模块是实现 URL 重写和.redirect 的强大工具。下面我们将详细介绍 Nginx 中如何使用 rewrite 实现二级域名、三级域名、泛域名、路径的重写。 二级域名重写 在 Nginx 中,使用 rewrite 可以实现...
### 实例讲解Nginx的...通过上述实例和解释,我们可以看到Nginx中的`rewrite`规则是非常强大且灵活的,它不仅可以用于简单的URL重写,还可以根据不同的条件进行复杂的逻辑处理,从而实现更加高效和安全的服务配置。
在使用nginx配置rewrite中经常会遇到有的地方用last并不能工作,换成break就可以,其中的原理是对于根目录的理解有所区别,按我的测试结果大致是这样的。 location / { proxy_pass http://test; alias /home/...
Nginx中的rewrite模块是一个非常实用的功能,它允许用户在服务器中动态地重写URL,实现URL的灵活处理,包括URL重定向和内部跳转等操作。rewrite规则在nginx的配置文件中定义,通常在server、location和if指令块中...
与Apache的`mod_rewrite`模块相比,Nginx的`rewrite`规则在语法和工作方式上有所不同,这使得理解并熟练掌握Nginx的`rewrite`规则成为提升服务器配置能力的关键。 **1. Nginx与Apache的Rewrite规则对比** Apache的...
"Nginx_URL重写模块详解" Nginx_URL重写模块是Nginx服务器中一个非常强大且灵活的模块,允许使用正则表达式重写URI,并且可以根据相关变量复位向和选择不同的配置。下面是该模块的详细讲解: 一、break指令 break...
Nginx Rewrite规则相关指令有if、rewrite、set、return、break等,其中rewrite是最关键的指令。一个简单的Nginx Rewrite规则语法如下: rewrite ^/b/(.*)\.html /play.php?video=$1 break; 如果加上if语句,示例如下...
其Rewrite模块是用于实现URL重写和重定向的重要功能,常用于实现搜索引擎优化(SEO)、URL规范化、简化URL结构、安全保护等场景。 **使用场景详解:** 1. **URL地址跳转:** 这是最常见的使用场景之一。例如,当企业...
在Nginx服务器配置中,`...理解并熟练运用`proxy_pass`和`rewrite`,可以极大地增强Nginx的灵活性和功能性,满足各种复杂的Web服务需求。在实际部署中,需要根据业务场景进行合理配置,以达到最佳性能和稳定性。
**Nginx Rewrite规则配置详解** 在Web服务器优化和URL管理中,Nginx的Rewrite规则扮演着重要角色。它允许我们根据特定条件重写请求的URL,从而实现动态URL到静态URL的转换、URL规范化、路径重定向等。Nginx的...
**Nginx Rewrite 规则详解** `Nginx` 的 `rewrite` 模块用于重写请求的 URI,这在处理动态路由、URL美化、重定向等方面非常有用。`rewrite` 规则通常在 `location` 块内定义,以针对特定的 URL 路径执行。 1. **...
**Nginx中的Location与Rewrite用法详解** 在Nginx服务器配置中,`location`和`rewrite`是两个非常关键的指令,用于处理HTTP请求的路由和URL重写。理解并熟练运用这两个指令对于优化网站性能和提供灵活的URL管理至关...