Nginx location匹配分三阶段:先精确匹配(=)立即终止;再找最长前缀,若含^~则跳过正则;最后按序执行正则(~、~*),首个匹配即生效;普通前缀(如/)优先级最低,易被覆盖。

掌握 Nginx location 匹配优先级规则,核心不是背顺序,而是理解它分阶段筛选的执行逻辑。配置覆盖问题大多源于误判“哪条规则真正生效”,而不是规则写错了。只要理清三阶段流程,并在关键位置加控制,就能避免 404、静态资源丢失或代理失效。
精确匹配(=)是第一道闸口
只要请求 URI 和 location = /path 完全一致(忽略 query string,不接受多一个字符或斜杠),就立刻终止匹配,后续所有 location 都不检查。
-
location = /health只匹配/health,不匹配/health/、/healthz或/health?ts=1 - 哪怕它写在配置文件最底下,只要命中,就赢了——不用靠“写在前面”来抢优先级
- 适合高频短路径:如
location = /favicon.ico { return 204; },既快又干净
前缀匹配中 ^~ 是“急刹车”
没命中 = 时,Nginx 找所有前缀匹配(含 ^~ 和无修饰符的),选出 URI 最长的那个。但若最长的是 ^~,就直接用它,跳过全部正则。
-
location ^~ /api/匹配/api/v1/users,即使后面有location ~ \.json$,也不会执行 - 想确保静态资源不被正则劫持?统一用
^~:比如location ^~ /static/+location ^~ /assets/ - 别混用:
location ^~ /js/和location ~ \.js$同时存在,后者永远不生效
正则匹配只在“必要时”且“按顺序”跑
只有当最长前缀匹配是普通前缀(无 ^~),且它没拦截,Nginx 才从上到下逐条试 ~ 和 ~*,遇到第一个能匹配的就停。
- 顺序很重要:
location ~ \.(jpg|png)$写在location ~ \.jpg$前面,后者就永远不会触发 - 边界要明确:用
~ \.php$,别写~ php$,否则会错误匹配/backup.php.bak - 大小写注意:
~ \.JPG$不匹配.jpg;需要兼容就用~* \.jpg$
普通前缀(无修饰符)是兜底,但最易被覆盖
location /admin 这类写法属于普通前缀,在四层里优先级最低。它只在没有 =、没有更优 ^~、也没被正则截胡时才生效。
-
location /admin实际匹配所有以/admin开头的路径,包括/admin/login、/admin-api - 如果还写了
location ~ \.php$,那么/admin/index.php就会进正则块——可能绕过你为/admin设的 auth 或 proxy_pass - 想精准控制?把权限或代理逻辑提前:用
location ^~ /admin/拦住目录,再单独配location = /admin处理首页










