01. Location 匹配规则详解
location 是 Nginx 配置的灵魂——它决定了对不同 URL 路径怎么处理。Nginx 收到请求后按优先级匹配 location:
匹配优先级(从高到低):
1. 精确匹配 = /exact(最优先,完全一样才匹配)
2. 前缀匹配 ^~ /prefix(匹配后不再检查正则)
3. 正则匹配 ~(区分大小写的正则)或 ~*(不区分大小写的正则)
4. 普通前缀匹配 /prefix(兜底)
正则匹配中,Nginx 会按在配置文件里的顺序找第一个匹配的。前缀匹配选最长的那个。
特殊规则:当一个请求匹配到多个 location,Nginx 最终只用 1 个(不会叠加)。优先级规则要牢记。
nginx
# 精确匹配
location = /favicon.ico {
# 只匹配 /favicon.ico
}
# 前缀匹配(优先)
location ^~ /static/ {
# 以 /static/ 开头的都走这里,正则不管了
}
# 正则匹配
location ~ \.php$ {
# 以 .php 结尾的走这里
}
location ~* \.(jpg|png)$ {
# jpg 或 png 走这里,不区分大小写
}
# 普通前缀匹配(兜底)
location / {
# 所有请求都匹配,但优先级最低
}正则匹配 ~ 和 ~* 是按配置文件里的顺序匹配的——第一个匹配的就用。所以比较特殊的正则放前面,宽泛的放后面。
02. 常用 location 配置场景
各种实际场景的 location 配置:
API 代理——/api/ 的请求转发到后端服务。
静态资源——/static/ 或特定文件后缀的直接返回文件。
健康检查——/health 返回 200 给负载均衡器。
ACME 验证——/.well-known/acme-challenge/ 给 Let's Encrypt 验证用。
顺序很重要——精确匹配和特定前缀放前面,兜底的 / 放最后。API 代理一般在静态资源之前还是之后?看需求但通常 API location 放前面,因为它匹配条件更精确。
nginx
# 典型的 location 配置顺序
# 1. 精确匹配(健康检查)
location = /health {
return 200 "ok";
add_header Content-Type text/plain;
}
# 2. Let's Encrypt 验证
location ^~ /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# 3. API 代理
location /api/ {
proxy_pass http://backend:3000;
}
# 4. 静态文件
location /static/ {
expires 30d;
}
# 5. 兜底
location / {
try_files $uri /index.html;
}03. 正则表达式在 location 里的应用
location 的正则匹配很强大,但别滥搞——过于复杂的正则影响性能且易出 bug。
常用正则 pattern:
~ \.php$——以 .php 结尾
~* \.(jpg|png|gif|css|js)$——常见静态文件后缀
~ ^/user/(\d+)——URL 里带数字 id,如 /user/123
正则匹配里用小括号捕获组,可以在后面用 $1 引用:
rewrite ^/old-page$ /new-page permanent;
rewrite ^/user/(\d+)$ /profile?id=$1 last;
last 告诉 Nginx 用重写后的 URI 重新走一遍 location 匹配。permanent 返回 301 给浏览器。redirect 返回 302。break 停止当前上下文继续执行为后续指令。
nginx
# 正则 location
location ~ ^/api/v[12]/ {
# 匹配 /api/v1/ 或 /api/v2/
proxy_pass http://backend;
}
# rewrite 重写
location / {
rewrite ^/blog/(.*)$ /posts/$1 last;
# /blog/my-post 变成 /posts/my-post
}
# 把老 URL 301 跳转
server {
listen 80;
server_name old.example.com;
return 301 https://new.example.com$request_uri;
}rewrite 里的 last 和 break 容易搞混——last 让 Nginx 用新 URI 重新匹配 location,break 在当前 location 里继续执行后续指令。
04. location 嵌套
一个 location 里面可以再写 location——这在前后缀代理转发时很实用。
场景:/api/ 代理到后端,但 /api/public/ 不需要认证(公开接口),可以用嵌套 location 细分:
外层 location /api/ { proxy_pass ...; } 作为默认处理,内层 location /api/public/ {} 覆盖特定的子路径。
嵌套的 location 里也可以用 proxy_pass 覆盖外层的代理设置,或者用 break/return 阻止代理。
nginx
# location 嵌套
location /api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
# 公开 API 不需要认证头
location /api/public/ {
proxy_pass http://backend;
proxy_set_header Authorization ""; # 清空认证头
}
# 管理 API 走另一个后端
location /api/admin/ {
proxy_pass http://admin-backend:3001;
}
}05. try_files 的高级用法
try_files 不只是 SPA 兜底,还有其他高级用法:
1. 尝试多个文件:try_files $uri $uri/ $uri.html =404; ——先看原始 URI,然后看是不是目录,再试加 .html,都不行返回 404。
2. 命名 location 配合:try_files $uri @fallback; ——如果找不到文件就跳到命名 location @fallback。
3. 用变量构建动态路径:try_files /cache$uri /app$uri =404; ——实现多层缓存查找。
4. 配合 proxy_pass 做缓存代理:先试本地有没有缓存文件,没有再代理到后端。
nginx
# try_files 配合命名 location
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass http://app:3000;
proxy_cache my_cache;
proxy_cache_valid 200 10m;
}
# 多层文件查找
location /images/ {
try_files /thumbnails$uri $uri =404;
# 先找缩略图,没有就找原图
}命名 location 以 @ 开头,不会直接响应请求,只能被 try_files 或 error_page 等指令引用。
知识测验
第 1/5 题正确 0
Nginx location 匹配里优先级最高的是?
下一节
下一节 安全配置