nginx location匹配严格分阶段:先精确(=)匹配完整路径且不带斜杠/参数,再按序执行正则(~/~*),二者不可混用同一行。

location精确匹配和正则匹配不能混用在同一行,必须分开定义,且顺序不决定优先级——Nginx按固定规则逐层比对,先找精确,再看前缀与正则的协作关系。
精确匹配(=)怎么写才生效
使用 = 修饰符,后面紧跟完整路径,不带尾部斜杠、不处理查询参数、不支持正则符号。
- 请求
/login→ 匹配location = /login { ... } - 请求
/login/或/login?next=/home→ 不匹配该规则(前者多斜杠,后者参数被忽略但路径本身不符) - 不能写成
location = /login/去匹配带斜杠的请求,除非客户端真发的是无参且结尾带斜杠的 URI - 多个
=规则互不干扰,各自独立触发,比如同时配置= /和= /health都有效
正则匹配(~ 和 ~*)的关键写法
正则匹配在精确匹配之后执行,区分大小写(~)或不区分(~*),按配置文件中出现顺序依次尝试,命中即停。
-
location ~ \.js$:只匹配以 .js 结尾的 URI,如/static/app.js,但不匹配/API.JS -
location ~* \.(css|png|jpg)$:统一小写后比对,/IMG.PNG和/style.CSS都能命中 - 正则中不能用
$uri变量,直接写字面正则;特殊字符如点、括号、美元符需转义 - 避免过度宽泛,例如
location ~ .*会拦截所有未被前面规则捕获的请求,容易掩盖真实问题
精确和正则共存时的真实行为
两者不是“谁在上面谁优先”,而是 Nginx 内部有明确的分阶段匹配流程:先扫一遍所有 =,再扫 ^~,再按顺序扫 ~/~*,最后 fallback 到普通前缀。正则不会覆盖精确匹配。
- 即使你在文件底部写了
location ~ /login,只要上面有location = /login,所有/login请求都走精确分支 - 若想让某个正则更早生效,只能把它往前挪,但永远无法越过
=和^~的阶段 - 测试时可用
curl -I http://host/path看响应头中的 Server 或自定义 header,验证到底进了哪个 location 块











