Nginx中的if指令详解
if指令用来判断条件表达式的结果,为true时执行的指令,条件为false时不执行相应的指令,if指令只能用在server、location内。
01
if指令的格式如下:
if (condition
) { ... }
condition可以是如下类型:
- 变量名,如果变量的值是空字符串或者0表示false
- 变量使用“=”和“!=”来跟字符串比较
- 可以是正则表达式
- 检查文件是否存在使用“-f” 和 “!-f”
- 检查目录是否存在使用 “-d” 和 “!-d”
- 检查文件、目录、符号链接是否存在使用 “-e” 和 “!-e”
- 检查是否是可执行文件使用“-x” 和 “!-x”
if指令不支持多条件、不支持嵌套、不支持else,与常见的条件表达式不同的特点是,if指令使用单个等号=而不是双等号==表达等值比较。
02
if是一个危险的指令,除了需要判断一个变量的值时必要使用if,其它情况能不使用if,尽量不用if,使用if时要仔细思考可能会出现的执行结果,稍不注意就会碰到遇想不到的执行结果。大多数人都按过程化的思路来判断结果,但nginx还有很多上下文环境需要考虑,不完全是从上到下按顺序执行。
比较安全的用法是满足if条件时只执行return指令。大括号{}内尽量只使用下面两种指令。否则,nginx可能不会按照你预想的顺序执行,严重的情况下可能会导致nginx段错误崩溃。
- return ...;
- rewrite ... last;
还有就是尽量别在location中使用if,在server中使用if相对会安全些。
03
如果要在location中使用if,最好用如下模版格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
location / { error_page 418 = @other; recursive_error_pages on; if ($something) { return 418; } # some configuration ... } location @other { # some other configuration ... } |
04
nginx不支持下面这样的多条件if:
1 |
if ($request_method = POST && $http_cookie ~* "CCCC=.+(?:;|$)") |
变通办法是:
1 2 3 4 5 6 7 8 9 |
if ($request_method = POST) { set $test P; } if ($http_cookie ~* "CCCC=.+(?:;|$)" ) { set $test "${test}C"; } if ($test = PC) { #rewrite rule goes here. } |
最后,有想深入了解if指令运行原理的同学,可以参考https://agentzh.blogspot.com/2011/03/how-nginx-location-if-works.html
分类: nginx