全书目录

第十七篇:Nginx 完全指南 —— 城市总闸口宇宙

第五章:location 匹配 —— 进了闸门,还得知道走哪条车道

1 分钟 255 字 第 325 / 962 个阅读单元

很多 Nginx 问题,根源都不在代理、不在 HTTPS,而在 location 没想清楚。

先看一个例子:

nginx
server {
    listen 80;
    server_name example.com;

    location = /healthz {
        return 200 "ok\n";
    }

    location ^~ /assets/ {
        root /srv/www/site;
    }

    location /api/ {
        proxy_pass http://api_backend;
    }

    location ~* \.(png|jpg|jpeg|gif|svg|css|js)$ {
        root /srv/www/site;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

你要记住的匹配顺序,不是“看起来谁像谁”,而是固定规则:

text
1. 先查精确匹配:location = /xxx
2. 再找前缀匹配里“最长”的那一个
3. 如果这个最长前缀带 ^~,就停止,不再试正则
4. 否则按书写顺序检查正则 location
5. 正则没有命中,回到刚才记住的最长前缀

可以压成一张小图:

text
请求 URI
  |
  +--> 精确匹配 = ?
  |       |
  |       +--> 命中,直接用
  |
  +--> 最长前缀是谁?
          |
          +--> 带 ^~ ? ----> 是 -> 直接用
          |
          +--> 否 -> 继续试正则
                         |
                         +--> 第一个命中的正则
                         |
                         +--> 没有 -> 回退到最长前缀

这就是为什么 location 一乱,整个城市总闸口的分流就乱。

最常见的三种车道写法:

  • location = /healthz:只匹配一个点位,适合健康检查。
  • location /api/:前缀车道,适合某个目录树。
  • location ~ \.php$location ~* \.(js|css)$:正则车道,适合模式匹配。