Published on
1118

Nginx 路径处理避坑指南:一文读懂 root、alias 与 proxy_pass

Authors
  • avatar
    Name
    小辉辉
    Twitter

静态文件服务:root 与 alias 的“拼接”与“替换”

这俩指令都是用来找文件的,但 Nginx 处理它们的方式完全不一样。

核心区别

  • root(拼接模式):你可以把它理解为“傻瓜式拼接”。Nginx 会把你 location 里的路径,直接追加到 root 指定的目录后面。
  • alias(替换模式):这个更像是“移花接木”。Nginx 会用 alias 指定的目录,直接把 location 匹配到的那部分路径给替换掉。

场景演示

假设你访问的网址是:http://example.com/images/logo.png

  1. 使用 root

    location /images/ {
        root /var/www/data;
    }
    
    • Nginx 的脑回路root 目录是 /var/www/data,请求路径是 /images/logo.png,那我把它俩拼起来。
    • 实际去找/var/www/data/images/logo.png
    • 适用场景:你的 URL 路径和服务器上的文件夹结构是一模一样的,用 root 最省事。
  2. 使用 alias

    location /images/ {
        alias /var/www/pictures/;
    }
    
    • Nginx 的脑回路alias 说要替换 /images/,那我就把 /images/ 扔掉,换成 /var/www/pictures/,剩下的 logo.png 拼在后面。
    • 实际去找/var/www/pictures/logo.png
    • 适用场景:你的 URL 想写得很漂亮(比如 /images/),但文件实际存在一个很深的奇怪目录(比如 /opt/app/static/assets/)里,这时候就得用 alias 来做个映射。

避坑指南

  • alias 必须加斜杠:这是个大坑!写 alias 的时候,路径末尾一定要加 /。如果你写成 alias /var/www/pictures(没斜杠),Nginx 可能会把请求拼成 /var/www/pictureslogo.png,直接报错。
  • 正则匹配:如果你在用正则 location 的时候搭配 alias,记得一定要用捕获组(比如 $1)来告诉 Nginx 文件名在哪,不然它找不到文件的。

Location 匹配:末尾那个斜杠到底要不要?

location /xlocation /x/ 看着差不多,但匹配范围差远了。

  • location /x(无前缀匹配):这是个“模糊匹配”。它会抓住所有以 /x 开头的请求。
    • 匹配:/x/x//xyz/xml
    • 风险:容易误伤。比如你想配 /app,结果 /application 也被抓进去了,这肯定不行。
  • location /x/(目录匹配):这是个“精确匹配”。它只认以 /x/ 开头的路径。
    • 匹配:/x//x/file
    • 不匹配:/x(通常会触发 301 重定向)、/xyz
    • 建议:配静态文件夹的时候,强烈建议加上斜杠,这样最稳,不会误伤其他路径。

反向代理:proxy_pass 的拼接逻辑

proxy_pass 是反向代理的核心,但那个末尾的斜杠 / 简直是玄学,决定了你的请求路径是“保留”还是“被砍掉”。

假设你配置了 location /api/,用户访问的是 /api/test

不带斜杠:原样透传

location /api/ {
    proxy_pass http://backend;
}
  • 逻辑:Nginx 觉得你只指定了主机,没指定路径,所以它会把原始请求 URI 完整拼接到后面。
  • 结果http://backend + /api/test -> http://backend/api/test
  • 场景:后端服务也是按 /api/ 路由的,你不想改路径,原封不动转过去。

带斜杠:剥离前缀

location /api/ {
    proxy_pass http://backend/;
}
  • 逻辑:一旦你加了 /,Nginx 就认为你要“替换”路径。它会先把 location 匹配到的 /api/ 切掉,把剩下的 test 拼到 proxy_pass 后面。
  • 结果http://backend/ + test -> http://backend/test
  • 场景:后端服务不知道 /api/ 这个前缀,或者你想隐藏这个前缀,只把核心路径转过去。

常见陷阱:路径粘连

如果你写成 proxy_pass http://backend/api(末尾没斜杠),Nginx 会执行“拼接”逻辑:

  • 结果/api(你指定的) + /api/test(原始请求) = /apiapi/test
  • 结论:除非你明确知道自己在做什么,否则在 proxy_pass 里指定路径时,请务必以 / 结尾,这样逻辑才清晰。

总结速查表

指令/场景关键配置核心逻辑推荐实践
静态文件root路径拼接 (root + location)目录结构一致时使用
静态文件alias路径替换 (alias 替换 location)必须加末尾斜杠 /
Location/x前缀匹配 (可能误伤 /xyz)API 接口或逻辑路径
Location/x/目录匹配 (精确匹配)静态资源文件夹
反向代理proxy_pass .../路径替换 (剥离 location 前缀)需要修改路径结构时
反向代理proxy_pass ...路径拼接 (保留完整 URI)路径透传时

把这些规则记在脑子里,下次配 Nginx 的时候就能一眼看出问题在哪,再也不用对着 404 发愁了!