我不明白 break 和 last(重写标志)之间的区别。文档相当深奥。我尝试在某些配置中在两者之间切换,但我没有发现任何行为差异。有人可以更详细地解释这些标志吗?最好举一个例子来展示将一个标志翻转为另一个标志时的不同行为。
答案1
您可能针对不同的位置设置了不同的重写规则集。当重写模块满足 时last
,它会停止处理当前集,并再次传递重写请求以查找适当的位置(以及新的重写规则集)。如果规则以 结尾break
,则重写也会停止,但重写请求不会传递到另一个位置。
也就是说,如果有两个位置:loc1 和 loc2,并且 loc1 中有一个重写规则,将 loc1 更改为 loc2 并且以 结尾last
,则请求将被重写并传递到位置 loc2。如果规则以 结尾break
,则它将属于位置 loc1。
答案2
OP 更喜欢举个例子。另外,@minaev 写的只是故事的一部分!所以,我们开始吧……
示例 1:无(中断或最后)标志
server {
server_name example.com;
root 'path/to/somewhere';
location / {
echo 'finally matched location /';
}
location /notes {
echo 'finally matched location /notes';
}
location /documents {
echo 'finally matched location /documents';
}
rewrite ^/([^/]+.txt)$ /notes/$1;
rewrite ^/notes/([^/]+.txt)$ /documents/$1;
}
结果:
# curl example.com/test.txt
finally matched location /documents
解释:
对于rewrite
,标志是可选的!
示例 2:外部位置块(中断或最后)
server {
server_name example.com;
root 'path/to/somewhere';
location / {
echo 'finally matched location /';
}
location /notes {
echo 'finally matched location /notes';
}
location /documents {
echo 'finally matched location /documents';
}
rewrite ^/([^/]+.txt)$ /notes/$1 break; # or last
rewrite ^/notes/([^/]+.txt)$ /documents/$1; # this is not parsed
}
结果:
# curl example.com/test.txt
finally matched location /notes
解释:
在位置块之外,break
和的last
行为方式完全相同......
- 不再解析重写条件
- Nginx 内部引擎进入下一阶段(搜索
location
匹配)
示例 3:位置块内部 - “break”
server {
server_name example.com;
root 'path/to/somewhere';
location / {
echo 'finally matched location /';
rewrite ^/([^/]+.txt)$ /notes/$1 break;
rewrite ^/notes/([^/]+.txt)$ /documents/$1; # this is not parsed
}
location /notes {
echo 'finally matched location /notes';
}
location /documents {
echo 'finally matched location /documents';
}
}
结果:
# curl example.com/test.txt
finally matched location /
解释:
在位置块内,break
标志将执行以下操作......
- 不再解析重写条件
- Nginx 内部引擎继续解析当前
location
块
示例 4:位置块内部 - “last”
server {
server_name example.com;
root 'path/to/somewhere';
location / {
echo 'finally matched location /';
rewrite ^/([^/]+.txt)$ /notes/$1 last;
rewrite ^/notes/([^/]+.txt)$ /documents/$1; # this is not parsed
}
location /notes {
echo 'finally matched location /notes';
rewrite ^/notes/([^/]+.txt)$ /documents/$1;
}
location /documents {
echo 'finally matched location /documents';
}
}
结果:
# curl example.com/test.txt
finally matched location /documents
解释:
在位置块内,last
标志将执行以下操作......
- 不再解析当前位置上下文重写条件
- Nginx 内部引擎开始看起来根据结果结果查找另一个位置匹配项
rewrite
,并在该位置上下文中应用重写规则
概括:
- 当
rewrite
带有标志break
或last
匹配的条件时,Nginx 将停止解析rewrites
! - 在位置块之外,使用
break
或last
,Nginx 执行相同的工作(停止处理任何重写条件)。 - 在位置块内,使用
break
,Nginx 仅停止处理重写条件 - 在位置块内,使用
last
,Nginx 停止处理任何重写条件,然后开始看起来进行新的区块匹配location
!
最后说明:
我忘记包含更多边缘情况(实际上是重写的常见问题,例如500 internal error
)。但是,这超出了这个问题的范围。可能,示例 1 也超出了范围!