我们来逐步拆解这段配置,并完整推导每个请求的匹配优先级,帮你彻底搞懂 Nginx 的 location 匹配规则。
一、配置原文
location = / { # A
[ config A ]
}
location ^~ /images/ { # B
[ config B ]
}
location ~* \.(gif|jpg|png|swf)$ { # C
[ config C ]
}
location /abc/def { # D
[ config D ]
}
location /abc { # E
[ config E ]
}
location / { # F
[ config F ]
}
二、Nginx location 匹配优先级规则(官方)
Nginx 在处理 location 时,严格按照以下优先级顺序(从高到低):
- 精确匹配
= - 前缀匹配
^~(一旦匹配,不再继续搜索正则) - 正则匹配
~/~*(按配置文件顺序) - 普通前缀匹配(最长匹配优先)
- 默认匹配
/
三、每个 location 的“类型”与优先级
| 编号 | 规则 | 类型 | 优先级等级 |
|---|---|---|---|
| A | = / | 精确匹配 | 最高(第1级) |
| B | ^~ /images/ | 前缀匹配(高优先级) | 第2级 |
| C | ~* \.(gif|jpg|png|swf)$ | 正则匹配 | 第3级 |
| D | /abc/def | 普通前缀匹配 | 第4级 |
| E | /abc | 普通前缀匹配 | 第4级(比 D 短) |
| F | / | 默认前缀匹配 | 最低 |
四、匹配流程(重点)
Nginx 的处理步骤:
第1步:先找 = 精确匹配
- 如果请求 URI 完全等于
/ - ✅ 直接命中 A,停止搜索,执行 config A
第2步:找 ^~ 前缀匹配
- 如果请求以
/images/开头 - ✅ 命中 B,停止搜索,执行 config B
- 即使后面有正则匹配到了,也不会执行
第3步:按顺序找 正则匹配(~ / ~*)
- 只有上面两步都没命中,才进入正则匹配
- 按配置文件顺序从上到下匹配
- 一旦命中第一个正则,立即执行,停止搜索
- 本例中只有 C 是正则
第4步:找 普通前缀匹配(最长优先)
- 如果所有正则都没命中
- 在普通前缀中,谁匹配的字符最多,就执行谁
- D 和 E 比较:
/abc/def长度 7/abc长度 3- ✅ 如果请求是
/abc/def,D 更长,执行 D - ✅ 如果请求是
/abc/xxx,E 是匹配前缀,执行 E
第5步:最后保底 /
- 如果以上全都不匹配
- ✅ 命中 F,执行 config F
五、请求匹配示例
| 请求 URI | 匹配规则 | 原因 |
|---|---|---|
/ | A | 精确匹配 = |
/index.html | F | 没有其他匹配,走默认 / |
/images/logo.png | B | ^~ /images/ 优先于正则 |
/abc/def/index.html | D | 最长普通前缀 /abc/def |
/abc/xyz | E | 最长普通前缀 /abc |
/xyz/abc.gif | C | 正则匹配 .gif 后缀 |
/abc/def.jpg | C | 注意!虽然 D 也是前缀,但正则优先于普通前缀 |
/images/abc/def.jpg | B | ^~ 直接拦截,不执行正则 |
六、最容易错的点(必看)
❗正则优先于普通前缀
很多人以为“长的普通前缀”会优先于正则,这是错的。
- 普通前缀(如 D/E/F)是在 正则匹配失败后 才考虑的
- 如果 C(正则)匹配上了,即使 D 是更长的前缀,也不会执行 D
✅ 验证:
/abc/def.jpg→ 匹配 C(正则.jpg$)- 即使
/abc/def更完整,但正则优先级高
七、一句话记忆口诀
等号最高,尖号次之,正则第三,最长前缀,斜杠保底
发表回复