[Nginx] if Is Evil
最近用nginx配置中使用if遇到一些问题,碰巧想起以前在wiki中看到的这个页面,虽然我的问题可能和wiki中提到的不同,但是if还是能避免就避免吧
下面的内容翻译自IfIsEvil
IfIsEvil (标题就不翻了,保持原汁原味的比较带感)
简介
if
指令在使用在location
上下文中时有一些问题。有时候它不能如你所愿,而是做一些完全相反的事情。有时候甚至会引发分段错误。通常来说应该尽量避免使用if
。
唯一100%可以安全的在location
上下文中使用if
的场景是:
任何其他情况都可能引发不可预知的行为,包括潜在的分段错误。
需要注意的是if
的行为并不是始终如一的。两个相同的请求不会在其中一个上失败而在另一个上成功,通过完善的测试并且对if
有深刻理解的话,它可以使用。但是仍然强烈建议使用其他指令来代替。
这些情况下可能你不能轻易的避免使用if
,比如说你想测试一个变量,就没有类似的指令可以替代。
1 2 3 4 5 6 |
|
用什么替代
在符合你的需求前提下,可以用try_files
代替。在其他情况下用”return …“或”rewrite … last”。在有些情况下可以将if
移动到server级别(在这里它是安全的,只有其他重写模块指令允许写在它里面)。
例如,下面的的用法在处理请求时可以安全的修改location
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
有些情况下,使用嵌入式脚本模块(嵌入式perl,或其他第三方模块)来写这些脚本。
例子
下面是一些例子用来解释为什么”if is evil”。不要在家里尝试这些,你被警告过了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
|
假如你发现了一个没有在上面列出来的例子 - 请将它报告给MaximDounin。
为什么这些问题存在但没有被修复
if
指令是重写模块的一部分而且是必须的。从另一方面说,nginx的配置通常来说是说明式的。有些用户希望尝试在if
指令中使用非重写的指令,这造成了这种处境。它大部分时间是有效的,但是。。。瞧上面。
看起来唯一正确的方式就是完全避免在if
中使用非重写指令。这会破坏很多已存在的配置,所以这没有被实施。
假如你还是想用if
假如你读了上面的内容仍然想用if
:
- 请确保你知道它是怎么工作的。一些基础知识可以看这里
- 做完整的测试
你被警告过了。