翻译内容可能已经过旧。
你可以通过 英文版本
查看最近的更新。
ngx_http_rewrite_module 模块允许正则替换URI,返回页面重定向,和按条件选择配置。
ngx_http_rewrite_module 模块指令按以下顺序处理:
-
处理在server级别中定义的模块指令;
-
为请求查找location;
-
处理在选中的location中定义的模块指令。如果指令改变了URI,按新的URI查找location。这个循环至多重复10次,之后nginx返回错误500 (Internal Server Error)。
指令
语法:
|
break;
|
默认值:
|
—
|
上下文:
|
server , location , if
|
停止处理当前这一轮的ngx_http_rewrite_module 指令集。
举例:
if ($slow) {
limit_rate 10k;
break;
}
语法:
|
if (condition ) { ... }
|
默认值:
|
—
|
上下文:
|
server , location
|
计算指定的condition 的值。如果为真,执行定义在大括号中的rewrite模块指令,并将if 指令中的配置指定给请求。if 指令会从上一层配置中继承配置。
条件可以是下列任意一种:
-
变量名;如果变量值为空或者是以“
0 ”开始的字符串,则条件为假;
-
使用“
= ”和“!= ”运算符比较变量和字符串;
-
使用“
~ ”(大小写敏感)和“~* ”(大小写不敏感)运算符匹配变量和正则表达式。正则表达式可以包含匹配组,匹配结果后续可以使用变量$1 ..$9 引用。如果正则表达式中包含字符“} ”或者“; ”,整个表达式应该被包含在单引号或双引号的引用中。
-
使用“
-f ”和“!-f ”运算符检查文件是否存在;
-
使用“
-d ”和“!-d ”运算符检查目录是否存在;
-
使用“
-e ”和“!-e ”运算符检查文件、目录或符号链接是否存在;
-
使用“
-x ”和“!-x ”运算符检查可执行文件;
举例:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
if ($request_method = POST) {
return 405;
}
if ($slow) {
limit_rate 10k;
}
if ($invalid_referer) {
return 403;
}
内嵌变量$invalid_referer 的值是通过valid_referers指令设置的。
语法:
|
return code [text ];
return code URL ;
return URL ;
|
默认值:
|
—
|
上下文:
|
server , location , if
|
停止处理并返回指定code 给客户端。返回非标准的状态码444可以直接关闭连接而不返回响应头。
从0.8.42版开始,可以在指令中指定重定向的URL(状态码为301、302、303和307),或者指定响应体文本 (状态码为其它值)。响应体文本或重定向URL中可以包含变量。作为一种特殊情况,重定向URL可以简化为当前server的本地URI,那么完整的重定向URL将按照请求协议($scheme )、server_name_in_redirect指令和port_in_redirect指令的配置进行补全。
另外,状态码为302的临时重定向使用的URL 可以作为指令的唯一参数。该参数应该以“http:// ”、“https:// ”或者“https:// ”开始。URL 中可以包含变量。
0.7.51版本以前只能返回下面状态码:
204、400、402 — 406、408、410、411、413、416 和 500 — 504。
直到1.1.16和1.0.13版,状态码307才被认为是一种重定向。
语法:
|
rewrite
regex
replacement
[flag ];
|
默认值:
|
—
|
上下文:
|
server , location , if
|
如果指定的正则表达式能匹配URI,此URI将被replacement 参数定义的字符串改写。rewrite 指令按其在配置文件中出现的顺序执行。flag可以终止后续指令的执行。如果replacement的字符串以“http:// ”或“https:// ”开头,nginx将结束执行过程,并返回给客户端一个重定向。
可选的flag 参数可以是其中之一:
last
-
停止执行当前这一轮的
ngx_http_rewrite_module 指令集,然后查找匹配改变后URI的新location;
break
-
停止执行当前这一轮的
ngx_http_rewrite_module 指令集;
redirect
-
在replacement字符串未以“
http:// ”或“https:// ”开头时,使用返回状态码为302的临时重定向;
permanent
-
返回状态码为301的永久重定向。
完整的重定向URL将按照请求协议($scheme )、server_name_in_redirect指令和port_in_redirect指令的配置进行补全。
举例:
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
...
}
但是当上述指令写在“/download/ ”的location中时,应使用标志break 代替last ,否则nginx会重复10轮循环,然后返回错误500:
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
如果replacement 字符串包括新的请求参数,以往的请求参数会添加到新参数后面。如果不希望这样,在replacement字符串末尾加一个问号“?”,就可以避免,比如:
rewrite ^/users/(.*)$ /show?user=$1? last;
如果正则表达式中包含字符“} ”或者“; ”,整个表达式应该被包含在单引号或双引号的引用中。
语法:
|
rewrite_log on | off ;
|
默认值:
|
rewrite_log off;
|
上下文:
|
http , server , location , if
|
开启或者关闭将ngx_http_rewrite_module 模块指令的处理日志以notice 级别记录到错误日志中。
语法:
|
set variable value ;
|
默认值:
|
—
|
上下文:
|
server , location , if
|
为指定变量variable 设置变量值value 。value 可以包含文本、变量或者它们的组合。
语法:
|
uninitialized_variable_warn on | off ;
|
默认值:
|
uninitialized_variable_warn on;
|
上下文:
|
http , server , location , if
|
控制是否记录变量未初始化的警告到日志。
内部实现
ngx_http_rewrite_module 模块的指令在解析配置阶段被编译成nginx内部指令。这些内部指令在处理请求时被解释执行。而解释器是一个简单的堆栈机器。
比如,下面指令
location /download/ {
if ($forbidden) {
return 403;
}
if ($slow) {
limit_rate 10k;
}
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
}
将被翻译成下面这些指令:
variable $forbidden
check against zero
return 403
end of code
variable $slow
check against zero
match of regular expression
copy "/"
copy $1
copy "/mp3/"
copy $2
copy ".mp3"
end of regular expression
end of code
请注意没有对应上面的limit_rate指令的内部指令,因为这个指令与ngx_http_rewrite_module 模块无关。nginx会为这个if块单独创建一个配置,包含limit_rate 等于10k。如果条件为真,nginx将把这个配置指派给请求。
指令
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
可以通过将正则表达式中的第一个斜线“/”放入圆括号,来实现节约一个内部指令:
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
对应的内部指令将会是这样:
match of regular expression
copy $1
copy "/mp3/"
copy $2
copy ".mp3"
end of regular expression
end of code
|