【原理揭秘】Nginx 匹配规则优先级详解
【原理揭秘】Nginx 匹配规则优先级详解
Nginx 的匹配机制看似简单,其实暗藏层层优先级:从
=、^~、~到普通前缀,谁先谁后?什么时候停止匹配?哪些规则会被跳过?本文带你彻底搞清楚。
🚀 一、四类匹配规则概览
| 优先级 | 类型 | 示例 | 匹配说明 |
|---|---|---|---|
| 1 | 精确匹配(=) | location = /index.html | 完全一致,优先级最高 |
| 2 | 前缀优先(^~) | location ^~ /static/ | 命中后不再进入正则 |
| 3 | 正则匹配(~ / ~*) | location ~ \.php$ | 区分大小写匹配 |
| 4 | 普通前缀匹配 | location /js/ | 默认兜底,按最长前缀匹配 |
💡 二、四种匹配详解
2.1 精确匹配(=)
location = /index.html {root /usr/share/nginx/html;
}
只匹配完全相同路径,如 /index.html。常用于首页、健康检查。
2.2 前缀优先(^~)
location ^~ /static/ {root /var/www;
}
匹配 /static/ 开头的请求后,将不再进入正则阶段。常用于静态目录。
2.3 正则匹配(~ / ~*)
location ~* \.(jpg|png)$ {root /data;
}
正则按书写顺序匹配,命中即停止。区分大小写与否由 ~ 或 ~* 决定。
2.4 普通前缀匹配
location /api/ { ... }
location /api/v1/ { ... }
在多个匹配中选择“最长前缀”,常用于接口路径。
三、匹配流程图
┌───────────────┐
│ 1️⃣ 精确匹配 (=) │→ 命中即返回
├───────────────┤
│ 2️⃣ 前缀优先 (^~) │→ 命中则跳过正则
├───────────────┤
│ 3️⃣ 正则 (~ / ~*) │→ 按定义顺序匹配
├───────────────┤
│ 4️⃣ 普通前缀匹配 │→ 选最长前缀
└───────────────┘
🧩 四、常见坑点
| 坑点 | 原因 | 修复 |
|---|---|---|
/js 没加 / | root 拼接丢斜杠 | 改为 /js/ |
| 正则写在前 | 抢走优先权 | 调整顺序 |
proxy_pass 尾部多 / | 路径拼接错 | 去掉多余 / |
🧱 五、总结
=:唯一、最高优先级。^~:静态目录首选,跳过正则。~ / ~*:复杂匹配,按顺序。- 普通前缀:默认兜底,取最长匹配。
👉 下一篇:《location /js 404?root 拼接才是罪魁祸首!》将带你看最常见的路径拼接坑。
【踩坑实录】location /js 404?root 拼接才是罪魁祸首!
明明文件存在
/usr/local/www/html/js/cc.js,访问/js/cc.js却报 404?
原因就在于一个不起眼的“斜杠”。
一、问题重现
location /js {root /usr/local/www/html;
}
访问 /js/cc.js → 404。文件确实存在、权限正确。问题出在哪?
二、根因分析:root 拼接机制
Nginx 直接拼接 root 与请求路径:
| 请求 | root | location | 实际路径 |
|---|---|---|---|
/js/cc.js | /usr/local/www/html | /js | /usr/local/www/htmljs/cc.js ❌ |
/js/cc.js | /usr/local/www/html | /js/ | /usr/local/www/html/js/cc.js ✅ |
三、正确写法
| 场景 | 正确写法 |
|---|---|
| 静态目录 | location /js/ { root /usr/local/html; } |
| 反向代理 | location /api { proxy_pass http://127.0.0.1:8080; } |
| 精确文件 | location = /index.html { ... } |
四、最佳实践
静态资源加
/,接口转发不加/,文件匹配用=。
【细节探秘】/js 与 /jsai 谁赢?Nginx 普通前缀匹配边界分析
当
/js和/jsai并存时,访问/js命中谁?是按书写顺序,还是按长度?
一、规则配置
location /js {return 200 "JS";
}
location /jsai {return 200 "JSAI";
}
请求 /js → 命中 /js。请求 /jsai → 命中 /jsai。
二、匹配原理
普通前缀匹配使用 最长前缀优先 原则:
- 收集所有能匹配请求路径的前缀。
- 从中选择匹配长度最长的那个。
/jsai 不会匹配 /js 请求,因为 /js 不是以 /jsai 开头。
三、拓展示例
| 请求 | 命中 |
|---|---|
/js | /js |
/jsa | /js |
/jsai | /jsai |
/jsai/test.js | /jsai |
四、尾斜杠的作用
建议在相似路径时明确区分:
location /js/ { ... }
location /jsai/ { ... }
这样能避免 /jsai 被 /js 模糊命中。
五、对比总结
| 匹配类型 | 比较方式 |
|---|---|
精确 = | 唯一匹配 |
前缀 ^~ | 长度优先 |
正则 ~ / ~* | 书写顺序优先 |
| 普通前缀 | 长度优先 |
✅ 一句话总结:“长度优先:普通前缀/^~;顺序优先:正则;唯一匹配:=”
如果这套系列帮你理清了思路,点赞 + 收藏 + 关注 🔥。
