极简工具箱

免费在线工具 · 本地计算 · 无需上传

Nginx 配置入门:location 匹配顺序与 proxy_pass 斜杠

同一个 location 写了三条规则却没生效,`proxy_pass` 加个斜杠就 404——Nginx 的规则不复杂,但顺序和细节很讲究。

广告位(百度联盟)

一、配置文件结构

events {}

http {
    server {
        listen 80;
        server_name www.it586.cn;

        location / {
            root /var/www/it586;
            index index.html;
        }
    }
}

一个 http 里可以有多个 server,每个 server 按 server_name 区分站点,location 按 URI 分流。

二、location 的匹配优先级

这是最容易搞错的部分,顺序是:

  1. = 精确匹配(最高)
  2. ^~ 前缀匹配(命中后不再尝试正则)
  3. ~ / ~* 正则匹配(按出现顺序,先匹配先生效)
  4. 普通前缀匹配(最长前缀优先)
location = /favicon.ico { }        # 只匹配这一个路径
location ^~ /static/ { }           # 以 /static/ 开头,且不再走正则
location ~* \.(jpg|png|css|js)$ { }  # 正则,忽略大小写
location / { }                     # 兜底

常见误区:写了 location /api/ 和 location ~ \.php$,以为 /api/x.php 会走前者,实际正则会先命中后者(因为普通前缀的优先级低于正则)。要拦住就用 ^~ /api/。

三、root 与 alias 的区别

# root:把完整 URI 拼到目录后面
location /img/ { root /data; }
# 请求 /img/a.png → /data/img/a.png

# alias:用 alias 替换掉 location 匹配的部分
location /img/ { alias /data/; }
# 请求 /img/a.png → /data/a.png

alias 末尾的斜杠必须与 location 一致,否则路径会拼错。这是 404 的高频原因。

四、try_files:SPA 与静态站必备

# 单页应用:文件不存在就交给 index.html
location / {
    root /var/www/app;
    try_files $uri $uri/ /index.html;
}

# 静态站:找不到就返回 404,不要回退
location / {
    root /var/www/site;
    try_files $uri $uri/ =404;
}

顺序是「先找文件 → 再找目录 → 最后回退」。静态站如果误写成回退到 index.html,所有不存在的 URL 都会返回 200 且内容相同,形成「软 404」,对 SEO 很不利。

五、proxy_pass 的斜杠陷阱

# 不带斜杠:原样转发完整 URI
location /api/ { proxy_pass http://127.0.0.1:8000; }
# /api/user → http://127.0.0.1:8000/api/user

# 带斜杠:替换掉 location 匹配的部分
location /api/ { proxy_pass http://127.0.0.1:8000/; }
# /api/user → http://127.0.0.1:8000/user

一个斜杠决定了后端收到的是 /api/user 还是 /user,这是「本地正常、线上 404」的常见原因。

反代还要带上这几个头,否则后端拿不到真实客户端信息:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

六、静态资源与压缩

gzip on;
gzip_min_length 1k;
gzip_types text/css application/javascript application/json image/svg+xml;

location ~* \.(css|js|png|jpg|svg|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

注意:HTML 不要设长缓存(内容会更新),带 hash 的静态资源才可以设一年。

七、改完必须做的事

nginx -t                 # 检查语法,务必先执行
nginx -s reload          # 平滑重载,不中断连接

nginx -t 会指出具体行号。直接 reload 而不检查,配置有错时旧进程仍在跑,看起来「没生效」,实际是新配置根本没加载。

八、排查思路

状态码含义可参考 HTTP 状态码详解,端口是否被占用用 端口查询 对照。

小结

匹配优先级 = > ^~ > 正则 > 前缀;root 拼完整 URI、alias 做替换;SPA 用 try_files ... /index.html,静态站用 =404;proxy_pass 的斜杠决定后端收到的路径。

本文相关工具(本地计算,无需上传)

更多使用教程