=
据我所知,^~
都是普通字符串前缀修饰符(既不是'reg-exp' 修饰符)。两者都只允许精确匹配(否则将被视为不匹配)。如果发现精确匹配,则两者都会停止进一步的匹配过程,并立即提供随附的“位置”。
那么这两个修饰符有什么区别呢?
答案1
据我所读/所理解,= 和 ^~ 都是普通字符串前缀修饰符(都不是“reg-exp”修饰符)。
=
是精确匹配,而不是前缀匹配^~
是一种“优先”前缀匹配,其优先级高于正则表达式匹配。换句话说,它与标准前缀位置相同,location /something
唯一的区别是,如果它与 URI 匹配,则不会搜索正则表达式位置。
两者都只允许完全匹配(否则将被视为不匹配)。
=
仅允许精确匹配,location = /foo
仅被视为匹配 URI/foo
(或/foo?some=arg
),而不匹配其他任何内容,例如foobar
不会匹配它^~
允许前缀匹配,例如location ^~ /foo
匹配/foo
和/foobar
和/fooanything
如果发现完全匹配,则停止进一步的匹配过程,并立即提供附带的“位置”。
那么这两个修饰符有什么区别呢?
如上所述,仅限=
精确匹配,只有一个 URI 基础可匹配,并且优先于其他匹配类型。
有^~
无限可能的匹配。这是两者之间的关键区别。
完全匹配的(=
)是性能最高效的匹配类型. 尽可能使用它:
location = /foo/bar/ { return 301 /foo; }
优于location ~ ^/foo/bar$ { return 301 /foo; }
。
如果您想拒绝对特定目录的访问,优先前缀匹配也很有意义,因为它不涉及正则表达式评估:
location ^~ /foo/ {
deny all;
}
将拒绝/foo/
目录内的任何内容,而不仅仅是/foo/
URI。
回顾一下:
# matching URIs: /foo, /foo?some=1, etc.
# fastest matching of all, highest priority
location = /foo { ... }
# matching URIs: /foo, /foob, /foob?some=1, /foobar, /foo[...]
# second fasted matching of all, the second highest priority
location ^~ /foo { ...}
答案2
更新
感谢@danila-vershinin 指出这一点,但=
实际上并没有定义前缀,而只是定义了精确匹配。请参阅他的回答以获得更完整/正确的答案。
以下是原始答案
=
如果您只有一个位置,那么您是对的,使用或都没关系^~
。当您有多个位置时,就会出现差异,不同的修饰符会影响最终匹配的顺序。
来自文档:
除非使用修饰符,否则正则表达式的优先级更高
^~
。在前缀字符串中,NGINX Plus 选择最具体的一个(即最长和最完整的字符串)。选择处理请求的位置的具体逻辑如下:
- 根据所有前缀字符串测试 URI。
- (等号)修饰符
=
定义 URI 和前缀字符串的精确匹配。如果找到精确匹配,则搜索停止。- 如果
^~
(插入符号波浪号) 修饰符添加最长匹配的前缀字符串,则不会检查正则表达式。- 存储最长匹配的前缀字符串。
- 根据正则表达式测试 URI。
- 当找到第一个匹配的正则表达式时停止处理并使用相应的位置。
- 如果没有正则表达式匹配,则使用存储的前缀字符串对应的位置。
基本上,= /test
如果您想匹配精确的路径/test
,那么很有用,在这种情况下,所有进一步的处理(正则表达式)都会被省略。
如果未找到精确匹配项,则=
和^~
均为字首匹配,并从所有这些位置中选择最长的匹配。如果该匹配具有修饰符,^~
则将立即使用它,否则将首先检查正则表达式。
在具体示例中,如果您有位置= /test
并请求路径/test/bla.html
,则首先将检查所有其他正则表达式,并且只有当没有匹配时才会= /test
使用 。相反,如果您有^~ /test
并请求/test/bla.html
,则将使用此正则表达式,即使有匹配 的正则表达式也是如此*.html
。
附言
请注意,只有最长匹配前缀在这里很重要。如果您有两个位置:= /test
和^~ /test/bla
并且要求/test/bla/x.html
,那么^~ /test/bla
就是使用的,并且由于它有^~
,所以不会检查正则表达式。如果位置是^~ /test
和= /test/bla
,那么=
就是最长的,所以在这种情况下将检查正则表达式(并且^~ /test
完全忽略)。