Nginx location匹配按四阶段执行:1.精确匹配(=)优先且终止匹配;2.^~最长前缀匹配成功则跳过正则;3.正则按配置顺序首中即止;4.普通前缀为兜底项。

Nginx 的 location 匹配不是靠书写顺序决定的,而是按四阶段筛选逻辑执行的。真正起作用的是匹配类型本身的语义和阶段规则,而不是“谁写在前面谁优先”。
精确匹配(=)一锤定音
只要请求 URI 和 location = /path 完全一致(忽略 query string,不接受多/少斜杠、大小写差异),就立刻生效,后续所有 location 都不检查。
- 例如:
location = /login只匹配/login,不匹配/login/或/Login - 即使它写在配置文件最末尾,只要命中,就终止匹配
最长前缀匹配中,^~ 会急刹车
当没有 = 命中时,Nginx 会从所有前缀类 location(包括 ^~ 和普通 /path)中选出 URI 最长的那个。
- 如果这个最长匹配是
^~开头的,比如location ^~ /api/,那就直接采用,*跳过所有正则匹配(~和 `~`)** - 这意味着:
location ^~ /static/后面哪怕写了location ~ \.js$,对/static/app.js也完全无效
正则匹配按配置顺序首中即止
只有在既没命中 =、最长前缀又不是 ^~(或虽是 ^~ 但没覆盖当前请求)时,Nginx 才进入正则扫描阶段。
- 从上到下逐条比对
~和~*,遇到第一个能匹配的就停,不再往后看 - 所以
location ~ \.(jpg|png|gif)$必须放在location ~ \.jpg$前面,否则后者永远不触发 - 边界要写清楚:用
~ \.php$,别写~ php$,否则/backup.php.bak也会被误匹配
普通前缀(无修饰符)是兜底项
像 location /admin 这种,只在前面三类都没生效时才可能被选中。
- 它实际匹配所有以
/admin开头的路径,比如/admin/login、/admin-api - 但它极易被正则“截胡”:如果同时有
location ~ \.php$,那么/admin/index.php就会进正则块,可能绕过你为/admin设置的权限或代理规则
不复杂但容易忽略


















