nginx 中 location 匹配优先级遵循精确匹配、前缀匹配(区分普通与正则)、内部重定向的固定规则,合理设置的核心在于将高频访问或需严格控制的静态资源路径放在最前面,并将动态请求或默认兜底逻辑放在最后。具体做法是优先使用 = 定义精确路径以拦截特定文件,接着用普通前缀匹配处理目录级路由,最后通过 ~* 正则或无修饰符的前缀作为默认入口,确保请求在第一次匹配成功后立即停止后续搜索。

精确匹配与普通前缀匹配的冲突解决
当存在多个前缀匹配时,Nginx 会选取长度最长的普通前缀作为候选,但精确匹配(=)拥有最高优先级,会直接覆盖长度比较的结果。这意味着如果配置了 /api/data 和 = /api/data,请求 /api/data 只会进入精确匹配块,而不会触发普通前缀匹配,从而避免了逻辑重叠导致的意外行为。

server {
listen 80;
server_name example.com;
# 精确匹配:优先级最高,直接返回状态码
location = /favicon.ico {
log_not_found off;
access_log off;
return 204;
}
# 普通前缀匹配:最长匹配原则
location /images/ {
alias /var/www/images/;
expires 30d;
}
# 默认兜底:捕获所有未匹配请求
location / {
proxy_pass http://backend;
}
}
正则表达式匹配的短路机制
正则表达式匹配(~ 或 ~*)在所有前缀匹配完成后才会被评估,且一旦第一个正则匹配成功,Nginx 立即停止搜索并执行该块配置,不再检查后续的正则或前缀。这种“短路”特性意味着正则配置的顺序至关重要,应将范围最小、特异性最强的正则放在前面,通用的正则放在后面,防止高优先级规则被低优先级的通用正则误杀。

server {
listen 80;
server_name example.com;
# 正则匹配:按书写顺序执行,首个命中即终止
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm.sock;
include fastcgi_params;
}
location ~* \.(js|css|png|jpg)${
root /var/www/static;
expires 1y;
}
# 前缀匹配:仅在前缀都不匹配且无正则命中时生效
location / {
try_files $uri $uri/ /index.html;
}
}
基于 try_files 指令的循环检测问题
在使用 try_files 进行前端路由兜底时,若最后一个参数指向当前 location 路径而非实际文件,会导致 Nginx 陷入 500 内部重定向循环。例如在 location / 中配置 try_files $uri $uri/ /;,当请求 /app 且不存在对应文件或目录时,Nginx 会尝试重定向到 /,这再次触发 location /,形成无限循环。正确的做法是将最后一个参数指向具体的静态入口文件,如 /index.html,以确保重定向目标脱离当前 location 上下文或指向确定的物理文件。











