The rewrite module is the ngx_http_rewrite_module
module. Its main function is to rewrite the request URI, which is the module installed by default in Nginx. The rewrite module will match the rewrite URI according to the PCRE regularity, and then initiate an internal jump to match the location, or directly do a 30x redirect back to the client.
Instruction execution order
- First execute the rewrite module instructions in the server block in sequence to get the request URI after rewrite
-
Then loop through the following instructions
> 如果没有遇到中断循环标志,此循环最多执行10次,但是我们可以使用break指令来中断rewrite后的新一轮的循环
(1). According to the request URI after rewrite, match the defined location block
(2). Sequentially execute the rewrite module instructions in the matched location
instruction
break
Context: server, location, if
Stop executing the ngx_http_rewrite_module instruction set, but the instructions of other modules are not affected
.
server {
listen 8080;
# 此处 break 会停止执行 server 块的 return 指令(return 指令属于rewrite模块) # 如果把它注释掉 则所有请求进来都返回 ok
break; return 200 "ok"; location = /testbreak { break; return 200 $request_uri; proxy_pass http://127.0.0.1:8080/other; } location / { return 200 $request_uri; } } # 发送请求如下 # curl 127.0.0.1:8080/testbreak # /other # 可以看到 返回 `/other` 而不是 `/testbreak`,说明 `proxy_pass` 指令还是被执行了 # 也就是说 其他模块的指令是不会被 break 中断执行的 # (proxy_pass是ngx_http_proxy_module的指令)
if
Context: server, location
Decide whether to execute the content in the if block statement according to the specified conditions
Several judgment conditions in if
- One
变量名
, if the value of the variable $ variable is an empty string or the string "0", it is false 变量
Comparison with a string Equal to (=) Not equal to (! =)注意此处不要把相等当做赋值语句啊
变量
And a regular expression pattern matching may be operator (~
case-sensitive matching regular,~*
case-insensitive matching regular ,!~
!~*
non both front)- Check if the file exists
-f
( Use ) and!-f
(Does not exist) - Check whether the path exists
-d
(exist) and!-d
(not exist), and then judge whether it can be a string or a variable - Check whether the file, path, or link file exists
-e
(exists) and!-e
(exists), and then judge whether it can be a string or a variable - Check whether the file is executable
-x
(executable) and (unexecutable), and!-x
then judge whether it can be a string or a variable
Note that items 1, 2, and 3 above must be judged as variables. 4, 5, 6, 7 can be either variables or strings. The basic usage of -f / -d / -e / -x is consistent with bash .
set $variable "0";
if ($variable) { # 不会执行,因为 "0" 为 false break; } # 使用变量与正则表达式匹配 没有问题 if ( $http_host ~ "^star\.igrow\.cn$" ) { break; } # 字符串与正则表达式匹配 报错 if ( "star" ~ "^star\.igrow\.cn$" ) { break; } # 检查文件类的 字符串与变量均可 if ( !-f "/data.log" ) { break; } if ( !-f $filename ) { break; }
return
Context: server, location, if
return code [text];
return code URL;
return URL;
Stop processing and code
return the specified code to the client. The non-standard code
code 444 closes the connection without sending a response header.
Starting from the 0.8.42
version, the return
statement can specify the redirection url
(status codes can be as follows 301,302,303,307),
can also specify the response text content for other status codes, and the redirected url
and response text can be included 变量
.
There is a special case, is redirected url
can be specified for this local server urI
, this is the case, nginx
will be based on protocol requests $scheme
, server_name_in_redirect
and port_in_redirect
automatically generates a complete url
(to be described here is server_name_in_redirect
and port_in_redirect
instruction indicating whether the server
block server_name
and listen
the port For redirect
use)
# return code [text]; 返回 ok 给客户端
location = /ok {
return 200 "ok";
}
# return code URL; 临时重定向到 百度 location = /redirect { return 302 http://www.baidu.com; } # return URL; 和上面一样 默认也是临时重定向 location = /redirect { return http://www.baidu.com; }
rewrite
Context: server, location, if
rewrite regex replacement [flag];
rewrite
The instruction uses the specified regular expression regex
to match the request, urI
and if the match is successful, the replacement
change is used URI
. rewrite
The instructions are executed in the order they appear in the configuration file. The flag
flag can be used to terminate further processing of the instruction. If the replacement string replacement
starts with http://
, https://
or $ scheme
, it stops processing subsequent content and redirects directly back to the client.
String rewritten in the first casehttp://
location / {
# 当匹配 正则表达式 /test1/(.*)时 请求将被临时重定向到 http://www.$1.com
# 相当于 flag 写为 redirect
rewrite /test1/(.*) http://www.$1.com; return 200 "ok"; } # 在浏览器中输入 127.0.0.1:8080/test1/baidu # 则临时重定向到 www.baidu.com # 后面的 return 指令将没有机会执行了
The second case rewrites the string withouthttp://
location / {
rewrite /test1/(.*) www.$1.com;
return 200 "ok"; } # 发送请求如下 # curl 127.0.0.1:8080/test1/baidu # ok # 此处没有带http:// 所以只是简单的重写。请求的 uri 由 /test1/baidu 重写为 www.baidu.com # 因为会顺序执行 rewrite 指令 所以 下一步执行 return 指令 响应了 ok
The four flags of rewrite
last
Stop processing the currentngx_http_rewrite_module
instruction set and start searching for matches with the changedURI
oneslocation
; (because last means "continue" in English, it will continue to try to match and jump to other locations)break
Stop processing the currentngx_http_rewrite_module
instruction set, just like thebreak
instructions above ; ( break is "interrupt stop" )redirect
Return 302 for a temporary redirect. (It can be understood as "temporary rent")permanent
Return 301 permanent redirect. (It can be understood as "moving a new home")
# 没有rewrite 后面没有任何 flag 时就顺序执行
# 当 location 中没有 rewrite 模块指令可被执行时 就重写发起新一轮location匹配
location / {
# 不加 flag, 默认顺序执行
rewrite ^/test1 /test2; rewrite ^/test2 /test3; # 此处发起新一轮location匹配 uri为/test3 } location = /test2 { return 200 "/test2"; } location = /test3 { return 200 "/test3"; } # 发送如下请求 # curl 127.0.0.1:8080/test1 # /test3
The difference between last and break
Last and break, they will terminate the execution of other rewrite module instructions in this location,
but last immediately initiates a new round of location matching and break will not
location / {
rewrite ^/test1 /test2;
rewrite ^/test2 /test3 last; # 此处发起新一轮location匹配 uri为/test3 rewrite ^/test3 /test4; proxy_pass http://www.baidu.com; } location = /test2 { return 200 "/test2"; } location = /test3 { return 200 "/test3"; } location = /test4 { return 200 "/test4"; } # 发送如下请求 # curl 127.0.0.1:8080/test1 # /test3 当如果将上面的 location / 改成如下代码 location / { rewrite ^/test1 /test2; # 此处 不会 发起新一轮location匹配;当是会终止执行后续rewrite模块指令 重写后的uri为 /more/index.html rewrite ^/test2 /more/index.html break; rewrite /more/index\.html /test4; # 这条指令会被忽略 # 因为 proxy_pass 不是rewrite模块的指令 所以它不会被 break终止 proxy_pass https://www.baidu.com; } # 发送如下请求 # 浏览器输入 127.0.0.1:8080/test1 # 代理到 百度产品大全页面 https://www.baidu.com/more/index.html;
Request parameters after rewrite
If the replacement string replacement
contains new request parameters, the previous request parameters are appended after them. If you do n’t want the previous parameters, replacement
put a question mark at the end of the replacement string to avoid appending them .
# 由于最后加了个 ?,原来的请求参数将不会被追加到rewrite之后的url后面
rewrite ^/users/(.*)$ /show?user=$1? last;
rewrite_log
Context: http, server, location, if
Open or close rewrite
the log of module instruction execution. If it is enabled, the rewrite will record notice
the log of the next level to nginx
the error_log
default, which is closed by default off
Syntax: rewrite_log on | off;
set
Context: server, location, if
Set the value of the specified variable. Variable values can contain text, variables, or a combination of them.
location / {
set $var1 "host is ";
set $var2 $host; set $var3 " uri is $request_uri"; return 200 "response ok $var1$var2$var3"; } # 发送如下请求 # curl 127.0.0.1:8080/test # response ok host is 127.0.0.1 uri is /test
uninitialized_variable_warn
Context: http, server, location, if
Controls whether to log warnings about uninitialized variables. On by default
Internal realization
The ngx_http_rewrite_module
module instructions are compiled into the requested processing during the configuration phase to interpret internal instructions. The interpreter is a simple virtual stacking machine.
For example, the instruction
location /download/ { if ($forbidden) { return 403; } if ($slow) { limit_rate 10k; } rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break; }
Will be translated into the following instructions:
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
Please note that the limit_rate instruction above does not have any instructions because it has nothing to do with the ngx_http_rewrite_module
module . Create a separate configuration for the if block . If the condition is true, a request will be allocated for this configuration, whichlimit_rate
is equal to 10k.
instruction
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
If the first slash in the regular expression is placed in parentheses, it can be simplified:
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
The corresponding instructions will be as follows:
match of regular expression copy $1 copy "/mp3/" copy $2 copy ".mp3" end of regular expression end of code
location (non-rewrite module)
grammar
server
Used in blocks, such as:
- server {
- location expression {
- }
- }
location expression type
- If you write a path directly, it matches the path
- ~ Means perform a regular match, case sensitive
- ~ * Means perform a regular match, not case sensitive
- ^ ~ Indicates common character matching. Use prefix matching. If the match is successful, it will no longer match other locations.
- = Perform exact character matching. That is an exact match.
priority
- The equal sign type (=) has the highest priority. Once the match is successful, no other matches are found.
- ^ ~ Type expression. Once the match is successful, no other matches are found.
- Regular expression types (~~ *) take precedence. If the regularity of multiple locations can match, the longest regular expression is used.
- Regular string matching type. Match by prefix.