你是不是也遇到过这些情况明明配了location /api/请求却跑到了location /加了^~想让某个目录优先匹配结果还是不生效正则写了半天永远被另一个 location 抢走别猜了。Nginx location 的匹配顺序不是玄学是一套固定规则。今天我用一张流程图把你从“试错调试”里拉出来。一、先上全图建议保存文字版流程概览请求进来先检查有没有精准匹配 →有则停止没有则查找所有^~前缀匹配 →有最长匹配则停止没有^~则按文件顺序匹配正则~/~*→第一个命中即停止没有正则命中则选择最长的普通前缀匹配无修饰符二、逐条拆解配小例子1️⃣精准匹配 —— 最高优先级写法location /exact/uri规则URI 必须完全一致包括末尾斜杠匹配后立即停止不再检查其他任何 location。典型用途首页、登录接口等需要精确控制的路径。例子location /auth/login { return 200 exact login; } location /auth/ { return 200 prefix; }请求/auth/login→ 返回exact login精准命中请求/auth/login/→ 返回prefix精准不匹配走前缀2️⃣^~前缀匹配 —— 优先级高于正则写法location ^~ /static/规则匹配到最长的^~前缀后立即停止不再检查任何正则。典型用途静态资源目录不希望被正则干扰。例子location ^~ /static/ { return 200 static prefix; } location ~ \.css$ { return 200 css regex; }请求/static/style.css→ 返回static prefix^~直接命中正则没机会3️⃣~和~*正则匹配 —— 顺序敏感~区分大小写~*不区分大小写规则按照配置文件中出现的顺序依次匹配第一个命中即停止。⚠️ 重要正则匹配一旦命中不会再找更长的前缀。例子顺序决定结果location ~ \.php$ { return 200 php regex; } location ~ \.php$ { return 200 another php; # 永远不会执行 }请求/index.php→ 返回php regex错误示范location ~ \.php$ { include fastcgi_params; } location / { try_files $uri $uri/ /index.php; }这样所有 PHP 请求都会先被正则命中/里的try_files对 PHP 无效。4️⃣ 普通前缀匹配 —— 选最长不看顺序写法location /images/规则Nginx 会收集所有匹配的前缀选择长度最长的一个不是先出现的且不会因为普通前缀而停止还会继续检查正则。如果正则都没有命中最终就用这个最长前缀。例子location / { return 200 root; } location /images/ { return 200 images; } location /images/small/ { return 200 small; }请求/images/small/logo.png→ 返回small最长前缀请求/images/logo.png→ 返回images请求/index.html→ 返回root三、一张表总结所有修饰符修饰符类型匹配方式匹配后是否继续优先级精准匹配完全相等停止最高^~前缀匹配最长前缀停止次高~正则区分大小写正则匹配按顺序停止第三~*正则不区分大小写正则匹配按顺序停止第三无修饰符普通前缀最长前缀但继续查正则继续查正则最低四、三个新手最常遇到的典型问题附验证方法问题1以为/会“抢走”所有请求错误认知location /是通配符会拦截所有请求导致后面的正则不生效。真相Nginx 永远先检查正则只有正则全部不匹配时才会落到/上。验证方法在/里加一个自定义响应头然后用curl -I看有没有该头。location / { add_header X-Location root; } location ~ \.php$ { add_header X-Location php; }请求/index.php→ 响应头X-Location: php证明正则优先。问题2正则的顺序写错了导致不该匹配的匹配了错误配置location ~ \.(gif|jpg|png)$ { # 处理图片 } location ~ /admin/.*\.png$ { # 管理员专用图片 }请求/admin/logo.png会被第一个正则命中.png第二个永远无效。正确做法把更精确的正则写在前面。location ~ /admin/.*\.png$ { # 放前面 # 管理员专用图片 } location ~ \.(gif|jpg|png)$ { # 其他图片 }问题3location /api和location /api/不一样location /api会匹配/api123、/api/abc因为/api是前缀location /api/只匹配以/api/开头的 URI建议除非你明确需要匹配/api后不带斜杠的奇怪路径否则一律写成location /api/。五、一条命令验证当前 location 匹配结果你可以用 Nginx 的 debug 日志来查看实际匹配过程# 1. 重新编译 Nginx 时加上 --with-debug或使用包管理器安装的 debug 版本 # 2. 在配置中开启 debug 日志 error_log /var/log/nginx/error.log debug; # 3. 发起请求后查看日志 tail -f /var/log/nginx/error.log | grep -E location|using输出会类似using location ~ \.php$ (regex)或者using location ^~ /static/ (prefix)六、记忆口诀等号最高脱帽停正则顺序行前缀选最长“等号最高”优先级最高“脱帽停”^~像帽子匹配后停止“正则顺序行”正则按文件顺序命中即停“前缀选最长”普通前缀只选最长且最后才用