本文系统梳理 location 的匹配规则、优先级顺序,并结合示例说明常见误区,帮助你在实际配置中做到可预测、可控。
location 指令的匹配方式与优先级
Nginx 在接收到请求后,会按照固定的规则顺序对 location 进行匹配。
理解优先级,是正确配置的关键。
| 写法 | 示例 | 匹配方式 | 优先级 |
|---|---|---|---|
精确匹配 = | location = /foo | URI 必须完全一致 | 🥇 最高 |
前缀匹配 ^~ | location ^~ /images/ | 前缀匹配,且命中后不再进入正则匹配阶段 | 🥈 第二 |
正则匹配 ~ | location ~ .php$ | 区分大小写的正则 | 🥉 第三(正则中按书写顺序) |
正则匹配 ~* | location ~* .jpg$ | 忽略大小写的正则 | 同上 |
| 前缀匹配(普通) | location /foo | 前缀匹配,多个命中时取最长前缀 | 🏅 第四 |
通用匹配 / | location / | 默认兜底 | 最低 |
实际匹配流程(简化版)
可以用一句话概括:
先精确 → 再前缀 → 再正则 → 最后兜底
更完整的逻辑是:
- 先检查是否存在 精确匹配 (
=) - 再检查所有 前缀匹配(两种前缀),记录最长的一个
- 如果该前缀是
^~,直接命中并结束 - 否则进入 正则匹配(按配置顺序)
- 若正则未命中,则回退到最长的普通前缀匹配
常见配置示例
server {
# 1. 精确匹配:只匹配 /login
location = /login {
...
}
# 2. 静态资源:前缀匹配并阻断正则
location ^~ /static/ {
root /web/data;
}
# 3. 正则匹配:处理 PHP 请求
location ~ .php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}
# 4. 普通前缀匹配:API 转发
location /api {
proxy_pass http://api-backend;
}
# 5. 默认兜底
location / {
index index.html;
}
}
📍 实践建议
- 静态资源路径(如
/static/、/assets/)优先使用^~ - API、页面路由多使用普通前缀匹配
- 正则匹配谨慎使用,避免性能和可读性问题
易错点:proxy_pass 的路径拼接规则 ⚠️
proxy_pass结尾有/:替换 location 前缀
proxy_pass结尾无/:保留原始 URI
裁剪前缀(推荐用于 API 网关)
location /api/ {
proxy_pass http://backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# /api/user/list → http://backend/user/list
不裁剪前缀
location /api/ {
proxy_pass http://backend;
}
# /api/user/list → http://backend/api/user/list
root vs alias
路径结构一致用 root
路径结构不一致用 alias
alias 三大坑:
- location 要带 /
- alias 要带 /
- 正则要写 $1
alias 可以配合 try_files 使用,但要理解
$uri仍然是“原始 URI”,不会自动去掉 location 前缀。
对比表
| 项目 | root | alias |
|---|---|---|
| 路径拼接 | root + 完整URI | alias 替换 location 前缀 |
| 是否保留 location 前缀 | 保留 | 不保留 |
| 使用场景 | 常规静态目录 | 目录映射 |
| 正则 location | 不需要特殊处理 | 必须用 $1 |
总结
location的优先级不是配置顺序,而是语法规则=和^~是控制匹配行为的“利器”- 正则匹配应作为补充手段,而非主力方案
proxy_pass是否带/,直接决定请求路径是否被裁剪