本文摘自 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 / ✓ 匹配!返回结果
四、重要注意事项
- 匹配顺序是固定的,Nginx 严格按照优先级顺序检查
- 前缀匹配 (^~) 会跳过所有正则匹配,一旦匹配就不再检查正则
- 正则匹配按配置顺序,第一个匹配的正则表达式被使用
- 普通前缀匹配使用最长匹配原则
- 查询参数不影响路径匹配,/path 和 /path?query=1 匹配相同的 location
- 尾部斜杠有影响,/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。