- new,2022-06-07,chenxizhan1995@163.com
Module ngx_http_rewrite_module
该指令是 ngx_http_rewrite_module 模块提供的。
ngx_http_rewrite_module 模块这个模块有七个指令。
- break
- if
- return
- rewrite
- rewrite_log
- set
- uninitialized_variable_warn
该模块的用处是改写请求URI,实现这一目的使用的手段包括:PCRE、重定向、if 判断。
指令执行流程该模块的 break if return rewrite set 指令按如下规则执行
- 依次执行 server 块内的 ngx_http_rewrite_module 模块的指令
- 循环
该模块的 break if return rewrite set 指令按如下规则执行 - 依次执行 server 块内的 ngx_http_rewrite_module 模块的指令
- 循环
- 根据 URI 寻找匹配的 location
- 顺序执行 location 块内的 ngx_http_rewrite_module 模块的指令
- 若有 rewrite 指令,重复循环,但最多不超过 10 次。若需要第11次循环,则返回错误
Syntax: break; Default: — Context: server, location, if
Stops processing the current set of ngx_http_rewrite_module directives.
PS:只是终止 http_rewrite 指令的执行,其它模块的指令继续处理。
if 略读Syntax: if (condition) { ... }
Default: —
Context: server, location
return
Syntax: return code [text]; return code URL; return URL; Default: — Context: server, location, if
Stops processing and returns the specified code to a client.
根据文档
- return URL; 等价于 return 302 URL
- return code URL; 限定 code 为 302,303,307,308 之一
- return code [text]; 限定 code 为除 302,303,307,308 之外的
Syntax: rewrite regex replacement [flag]; Default: — Context: server, location, if
若 uri 与 rewrite 指令的 regex 匹配,则把它替换成 replacement。
无 flag 时,会顺序执行 rewreite 指令,设置了 flag 则根据其指示执行。
当 replacement 的开头是 http:// https:// 或者 $sheme:// 之一时,结束处理并直接返回客户端重定向。
flag 有如下四种
- break 终止 http_rewrite 模块指令的执行,继续执行其它模块的指令。
- last 终止 http_rewrite 模块指令的执行,用改写后的 URI 重新匹配 location。
- redirect 把 replacement 以 302 形式返回给客户端。当 replacement 的开头不是 http:// https:// 或者 $sheme:// 之一时,可以这样做。
- permanent 返回 301 永久重定向
关于 break 和 last 标志,大概的逻辑如下:
execute directvie in server;
labelA:
for (int i = 0; i< 10; i++){
location loc = search_location(uri);
for each directive in loc; do
switch (directive){
case "break": break labelA;
case "rewrite":
if (flag == NULL) continue;
if (flag == "last") continue labelA;
if (flag == "break") break labelA;
...
}
done
}
就是说,有这么一个最外层循环 labelA,它根据 uri 搜索 location,然后顺序执行其中的 http_rewrite 模块的指令,
遇到 break 指令,就终止整个循环;遇到 rewrite … break; 也终止整个循环,遇到 rewrite … last 则跳过本轮循环。
break 好比 for 循环的 break,结束的是整个 http_write 模块,
last 相当于 for 循环的 continue,结束的是 http_write 模块的本次循环,之后会重新匹配 location
server {
listen 80;
rewrite_log on;
root /usr/share/nginx/html;
location /hello {
rewrite ^/hello$ /hello2 last;
}
location /hello2 {
return 200 "$time_iso8601n";
}
}
如此配置,当访问 /hello 时,指令 rewrite ^/hello$ /hello2 last; 会把请求变为 /hello 然后重新
寻找 location,于是匹配到 /hello2。
如果 /hello 对应的 location 的指令改为 rewrite ^/hello$ /hello2 break;,则当访问 /hello 时,会把请求
重写为 /hello2,然后没有机会重新寻找 location 了,直接在 /hello 这个 location 中处理该请求,由于没有任何
配置,会寻找静态资源文件 /usr/share/nginx/html/hello2,当然找不到,会报 404错误。
demo-nginx/demo2



