Nginx Location 匹配优先级详解

本文摘自 deepseek

一、Location 匹配规则总览

Nginx 按以下顺序匹配 location(从高到低):

bash 复制代码
 1. 精确匹配 (location = /path)
 2. 前缀匹配 (location ^~ /path)
 3. 正则匹配 (区分大小写) (location ~ pattern)
 4. 正则匹配 (不区分大小写) (location ~* pattern)
 5. 普通前缀匹配 (location /path)
 6. 通用匹配 (location /)

二、每种匹配类型的详细解释和示例

1. 精确匹配 (Exact Match) location = /path

特点:
  • 只匹配完全相同的路径
  • 优先级最高
  • 匹配成功后立即停止搜索其他 location

示例配置:

bash 复制代码
server {
    listen 80;
    server_name example.com;
    
    # 精确匹配首页
    location = / {
        return 200 "This is homepage";
    }
    
    # 精确匹配登录页
    location = /login {
        return 200 "This is login page";
    }
    
    # 其他匹配
    location / {
        return 200 "General match";
    }
}

测试结果:

bash 复制代码
请求 /          → "This is homepage"    (精确匹配)
请求 /login     → "This is login page"  (精确匹配)  
请求 /login?user=abc → "This is login page"  (忽略查询参数)
请求 /login/    → "General match"       (不是精确匹配,多了斜杠)
请求 /api       → "General match"       (没有精确匹配)

2. 前缀匹配 (带 ^~) location ^~ /path

特点:
  • 匹配以指定路径开头的 URI
  • 优先级高于正则匹配
  • 匹配成功后不再检查正则表达式

示例配置

bash 复制代码
server {
    listen 80;
    server_name example.com;
    
    # 前缀匹配(高优先级)
    location ^~ /static/ {
        return 200 "Static files (prefix match)";
    }
    
    # 正则匹配
    location ~ \.(jpg|png|gif)$ {
        return 200 "Image file (regex match)";
    }
    
    location / {
        return 200 "General match";
    }
}

测试结果

bash 复制代码
请求 /static/logo.jpg   → "Static files (prefix match)"  (前缀匹配优先于正则)
请求 /images/photo.jpg  → "Image file (regex match)"     (正则匹配)
请求 /static/css/style.css → "Static files (prefix match)"
请求 /static/           → "Static files (prefix match)"

3. 正则匹配 (区分大小写) location ~ pattern

特点:
  • 使用正则表达式匹配
  • 区分大小写
  • 多个正则匹配时,按配置文件中的顺序匹配

示例配置:

bash 复制代码
server {
    listen 80;
    server_name example.com;
    
    # 正则匹配:图片文件
    location ~ \.(jpg|jpeg|png|gif)$ {
        return 200 "Image (case-sensitive regex)";
    }
    
    # 正则匹配:PHP文件
    location ~ \.php$ {
        return 200 "PHP file (case-sensitive regex)";
    }
    
    # 普通前缀匹配
    location /api/ {
        return 200 "API prefix";
    }
    
    location / {
        return 200 "General match";
    }
}

测试结果:

bash 复制代码
请求 /image.jpg         → "Image (case-sensitive regex)"
请求 /image.JPG         → "General match"  (大小写不匹配)
请求 /api/test.php      → "PHP file (case-sensitive regex)"  (正则优先于前缀)
请求 /api/users         → "API prefix"
请求 /docs/page.html    → "General match"

4. 正则匹配 (不区分大小写) location ~* pattern

特点:
  • 使用正则表达式匹配
  • 不区分大小写
  • 优先级与区分大小写的正则匹配相同,按顺序决定

示例配置:

bash 复制代码
server {
    listen 80;
    server_name example.com;
    
    # 不区分大小写的正则匹配
    location ~* \.(jpg|jpeg|png|gif)$ {
        return 200 "Image (case-insensitive regex)";
    }
    
    # 区分大小写的正则匹配
    location ~ \.pdf$ {
        return 200 "PDF file (case-sensitive regex)";
    }
    
    # 普通前缀匹配
    location /downloads/ {
        return 200 "Downloads directory";
    }
}

测试结果:

bash 复制代码
请求 /image.jpg         → "Image (case-insensitive regex)"
请求 /image.JPG         → "Image (case-insensitive regex)"  (大小写不敏感)
请求 /document.PDF      → "General match"  (大小写不匹配,pdf 需要小写)
请求 /document.pdf      → "PDF file (case-sensitive regex)"
请求 /downloads/image.png → "Image (case-insensitive regex)"  (正则优先于前缀)

5. 普通前缀匹配 location /path

特点:
  • 匹配以指定路径开头的 URI
  • 优先级最低(除了通用匹配)
  • 多个匹配时,使用最长匹配原则

示例配置:

bash 复制代码
server {
    listen 80;
    server_name example.com;
    
    # 普通前缀匹配 - 较长路径
    location /api/v2/ {
        return 200 "API v2";
    }
    
    # 普通前缀匹配 - 较短路径
    location /api/ {
        return 200 "API v1";
    }
    
    # 通用匹配
    location / {
        return 200 "General match";
    }
}

测试结果:

bash 复制代码
请求 /api/v2/users      → "API v2"        (最长匹配原则)
请求 /api/users         → "API v1"        (匹配/api/)
请求 /api               → "General match" (不匹配/api/,因为没有斜杠)
请求 /api/              → "API v1"        (匹配/api/)

6. 通用匹配 location /

特点:
  • 匹配所有请求
  • 优先级最低
  • 作为默认配置使用

示例配置:

bash 复制代码
server {
    listen 80;
    server_name example.com;
    
    # 精确匹配
    location = /admin {
        return 200 "Admin page (exact)";
    }
    
    # 正则匹配
    location ~ \.php$ {
        return 200 "PHP handler";
    }
    
    # 通用匹配(兜底)
    location / {
        return 200 "Default handler";
    }
}

测试结果:

bash 复制代码
请求 /admin            → "Admin page (exact)"
请求 /index.php        → "PHP handler"
请求 /about            → "Default handler"
请求 /contact          → "Default handler"

三、综合示例和匹配流程

综合配置示例:

bash 复制代码
server {
    listen 80;
    server_name example.com;
    
    # 1. 精确匹配
    location = / {
        return 200 "Homepage (exact match)";
    }
    
    # 2. 前缀匹配(高优先级)
    location ^~ /static/ {
        return 200 "Static content (priority prefix)";
    }
    
    # 3. 正则匹配(区分大小写)
    location ~ \.(php|php5)$ {
        return 200 "PHP script (case-sensitive regex)";
    }
    
    # 4. 正则匹配(不区分大小写)
    location ~* \.(jpg|jpeg|png|gif|ico)$ {
        return 200 "Image file (case-insensitive regex)";
    }
    
    # 5. 普通前缀匹配
    location /admin/ {
        return 200 "Admin area (prefix match)";
    }
    
    # 6. 普通前缀匹配
    location /api/ {
        return 200 "API endpoint (prefix match)";
    }
    
    # 7. 通用匹配
    location / {
        return 200 "Everything else (general match)";
    }
}

匹配流程演示:

bash 复制代码
请求 / → 
  1. 检查精确匹配: location = / ✓ 匹配!返回结果

请求 /static/css/style.css → 
  1. 检查精确匹配: 无
  2. 检查前缀匹配(^~): location ^~ /static/ ✓ 匹配!返回结果
  (不检查正则匹配)

请求 /static/image.PNG → 
  1. 检查精确匹配: 无
  2. 检查前缀匹配(^~): location ^~ /static/ ✓ 匹配!返回结果
  (虽然也匹配正则 location ~* \.(jpg|jpeg|png|gif|ico)$,但不检查)

请求 /index.php → 
  1. 检查精确匹配: 无
  2. 检查前缀匹配(^~): 无
  3. 检查正则匹配: location ~ \.(php|php5)$ ✓ 匹配!返回结果

请求 /IMAGE.jpg → 
  1. 检查精确匹配: 无
  2. 检查前缀匹配(^~): 无
  3. 检查正则匹配: location ~ \.(php|php5)$ 无
  4. 检查正则匹配(不区分大小写): location ~* \.(jpg|jpeg|png|gif|ico)$ ✓ 匹配!返回结果

请求 /admin/users → 
  1. 检查精确匹配: 无
  2. 检查前缀匹配(^~): 无
  3. 检查正则匹配: 无
  4. 检查正则匹配(不区分大小写): 无
  5. 检查普通前缀匹配: location /admin/ ✓ 匹配!返回结果

请求 /api/v1/users → 
  1. 检查精确匹配: 无
  2. 检查前缀匹配(^~): 无
  3. 检查正则匹配: 无
  4. 检查正则匹配(不区分大小写): 无
  5. 检查普通前缀匹配: location /api/ ✓ 匹配!返回结果

请求 /about → 
  1-6步都不匹配
  7. 通用匹配: location / ✓ 匹配!返回结果

四、重要注意事项

  1. 匹配顺序是固定的,Nginx 严格按照优先级顺序检查
  2. 前缀匹配 (^~) 会跳过所有正则匹配,一旦匹配就不再检查正则
  3. 正则匹配按配置顺序,第一个匹配的正则表达式被使用
  4. 普通前缀匹配使用最长匹配原则
  5. 查询参数不影响路径匹配,/path 和 /path?query=1 匹配相同的 location
  6. 尾部斜杠有影响,/path 和 /path/ 是不同路径

五、调试技巧

可以添加调试头来查看匹配情况:

bash 复制代码
location ~* \.(jpg|jpeg|png|gif)$ {
    add_header X-Location-Match "Case-insensitive regex for images";
    # ...
}

location /static/ {
    add_header X-Location-Match "Prefix match for static";
    # ...
}

这样可以通过响应头查看实际匹配的是哪个 location。

相关推荐
liucan20125 小时前
nginx服务器实现上传文件功能_使用nginx-upload-module模块
服务器·前端·nginx
摇滚侠8 小时前
Windows 版 Nginx 关闭
运维·windows·nginx
Meepo_haha12 小时前
Nginx 反向代理配置
运维·nginx
星辰徐哥14 小时前
C语言Web开发:CGI、FastCGI、Nginx深度解析
c语言·前端·nginx
sunwenjian88615 小时前
httpslocalhostindex 配置的nginx,一刷新就报404了
运维·nginx
bearpping16 小时前
nginx 代理 redis
运维·redis·nginx
ywf121516 小时前
Nginx 缓存清理
运维·nginx·缓存
dustcell.17 小时前
企业级高可用电商平台实战项目设计
运维·redis·nginx·docker·web·lvs·haproxy
chehaoman1 天前
Failed to restart nginx.service Unit nginx.service not found
运维·nginx
今晚务必早点睡1 天前
Nginx 从入门到精通:一篇讲透原理、功能、配置与实战场景
运维·nginx·负载均衡