五种匹配语法
location 后面跟的那一串决定了匹配方式,五种语法各一句话:= /path 精确匹配(URI 一字不差才算);^~ /path 前缀匹配+截断正则(命中就不再试正则);~ pattern 正则区分大小写;~* pattern 正则不区分大小写;/path 普通前缀匹配(最长优先,但会被正则截胡)。
优先级铁律
location = /health { return 200 "ok"; } # ① 精确匹配:命中即停
location ^~ /static/ { root /data/www; } # ② ^~:前缀命中后跳过正则
location ~* .(jpg|png|css|js)$ { # ③ 正则:按书写顺序取第一个命中
root /data/www;
expires 7d;
}
location /api/ { proxy_pass http://backend; } # ④ 普通前缀:最长优先
location / { proxy_pass http://backend; } # ⑤ 兜底
#
# 完整顺序:先找最长前缀并记住 → 若是 ^~ 直接用它,结束
# 否则按顺序试正则,第一个命中的赢,结束
# 正则全没中,用刚才记住的前缀
# 注意:① 一旦精确命中,整个匹配立即结束,谁都不用比背不下来就记一句"精确称王,^~ 截断正则,正则按序,前缀比长"。这条链决定了你配置的先后顺序——正则块之间的顺序是有语义的,别乱排。
两个经典的坑
坑一:正则顺序反了。想拦截所有 .php 直接 403,但这条正则写在前面,导致 /static/xxx.php 也被它吃掉,静态资源 403——把拦截规则放最后,或者用 ^~ 让静态前缀先截断正则。坑二:以为前缀最长就赢。location /static/ 匹配了 /static/logo.png,但一条 location ~ .png$ 会截胡它——除非前者写成 ^~。静态资源块用 ^~ 是实践里的标准姿势。
调试:命中了哪一条
想验证某 URI 落在哪个 location,最快的土办法:在各 location 里临时加 add_header X-Debug loc1 always; 然后用 curl -I 看响应头;正式手段是 error_log 开 debug 级看匹配过程。404 排查也顺着这条路:先确认命中了哪个 location,再看 root/alias 拼出的最终路径对不对——下一篇就讲反向代理里同样的"路径拼接"学问。
评论 (0)