前提: Nginx 配置文件默认:error_log logs/error.log info; #URL 重写模块的日志会写入此文件
注意: 打开 rewrite 模块的日志开关,以便 rewrite 执行日志写入 error_log ( rewrite 日志写入 error_log 的级别是 notice ,所以要注意 error_log 日志级别,此处用 info )参考http://eyesmore.iteye.com/blog/1142162.
location块
TEST 1
server {
listen 80;
server_name rewrite.test.cn;
root html; rewrite_log on; # 打开 URL 重写模块的日志开关,以便写入 error_log
location /a.html {#此块以下简称A
rewrite "^/a\.html$" /b.html;
rewrite "^/b\.html$" /d.html;
}
location /b.html {#此块为B
rewrite "^/b\.html$" /c.html;
}
}
测试:
结果:d.html
流程:匹配locationA->rewrite为b.html->rewrite为d.html->此时URI为新得URI,重新匹配->locationA匹配失败->locationB匹配失败->最终结果是d.html页面
结论:locaiton可以看做是while(true){..code}循环.
TEST 2
在上例location A第一个rewrite后面加上last标记
server {
listen 80;
server_name rewrite.test.cn;
root html;
rewrite_log on; # 打开 URL 重写模块的日志开关,以便写入 error_log
location /a.html {#此块以下简称A
rewrite "^/a\.html$" /b.html last;
rewrite "^/b\.html$" /d.html;
}
location /b.html {#此块为B
rewrite "^/b\.html$" /c.html;
}
}
测试:
结果:c.html
流程:匹配location A->rewrite为b.html->因有last标记,不在locaiton A里继续往下匹配而跳出->重新匹配->locaiton A失败(此时是uri是b.html)->匹配locaiton B->rewrite为c.html->重新匹配->location A,B都匹配失败->结果c.html
结论:location块的rewrite规则使用last标记,终止rewrite继续匹配.
TEST 3
上例的last标记改成break
server {
listen 80;
server_name rewrite.test.cn;
root html;
rewrite_log on; # 打开 URL 重写模块的日志开关,以便写入 error_log
location /a.html { #此块以下简称A
rewrite "^/a\.html$" /b.html break;
rewrite "^/b\.html$" /d.html;
}
location /b.html {#此块为B
rewrite "^/b\.html$" /c.html;
}
}
测试:
结果:b.html
流程:匹配location A->rewrite为b.html->因有break标记跳出当前locationA,终止rewrite->结果b.html
结论:break标记和last标记都有终止rewrite的作用,last可以理解成只对当前location块终止匹配之后还会重新匹配locaiton块,break标记终止是彻底的,不再带有拖泥带水,不继续往下执行,也不会重新匹配locaiton块.
TEST 4.1
rewrite移到server级别
server {
listen 80;
server_name rewrite.test.cn;
root html;
rewrite_log on; # 打开 URL 重写模块的日志开关,以便写入 error_log
rewrite "^/a\.html$" /b.html;
location /c.html { #此块以下简称A
rewrite "^/c\.html$" /e.html;
}
location /b.html {#此块为B
rewrite "^/b\.html$" /c.html;
rewrite "^/c\.html$" /d.html;
}
}
测试:
结果:d.html
流程:匹配server级rewrite为b.html->locationA失败->locationB成功->rewrite为c.html->rewrite为d.html->因为是locaiton级修改URI重新匹配->server级rewrite失败->locaitonA失败->locaitonB失败->结果d.html
结论:server级别的rewrite比locaiton级别高,优先执行,此例不明显.
TEST 4.2
调整上例顺序,server级别放到locaiton之后
server {
listen 80;
server_name rewrite.test.cn;
root html;
rewrite_log on; # 打开 URL 重写模块的日志开关,以便写入 error_log
location /c.html { #此块以下简称A
rewrite "^/c\.html$" /d.html;
rewrite "^/d\.html$" /e.html;
}
location /b.html {#此块为B
rewrite "^/b\.html$" /c.html;
}
rewrite "^/a\.html$" /b.html;
rewrite "^/c\.html$" /d.html;
}
测试:
结果:e.html
流程:匹配server级别rewrite为b.html->匹配locaiton级别A失败->locationB成功rewrite为c.html->locaiton级别修改URI重新迭代->匹配server级别rewrite失败->locationA成功->rewrite为d.html->rewrite为e.html->locaitonB失败->重新迭代->都失败->结果e.html
结论:server级别无论在location前后,因比locaition级别高,优先执行,再按顺序执行location级别.
server {
listen 80;
server_name rewrite.test.cn;
root html;
rewrite_log on; # 打开 URL 重写模块的日志开关,以便写入 error_log
rewrite "^/a\.html$" /b.html;
rewrite "^/c\.html$" /d.html;
location /b.html { #此块以下简称A
rewrite "^/b\.html$" /c.html;
}
location /d.html {#此块为B
rewrite "^/d\.html$" /e.html
流程:匹配server级rewrite为b.html->匹配locaitonA->rewrite为c.html->locaitonB失败->被locaiton级别rewrite改写重新迭代->匹配server级rewrite为d.html->匹配locationA失败->匹配locaitonB rewrite为e.html->重新迭代->server级别两个rewrite失败->locaitonA,B失败->结果e.html
--------------------------------------------分割------------------------------------------
目前有一个问题没有得到答案.
在同一个root目录下get和post(带参数)都可以成功rewrite.从root1跳到root2的时候,get可以,post只跳参数丢了..什么原因?
阅读(1119) | 评论(0) | 转发(0) |