引用:

Nginx的proxy_pass url 反向代理的配置 - cnkker.com - 博客园

一、基础 URL 格式规范

1. 无路径情况

合法格式:

  • http://host
  • https://host
  • http://host:port
  • https://host:port

非法格式:

  • http://host/
  • http://host:port/ (结尾不能有 /

2. 包含路径情况

合法格式:

  • http://host/
  • https://host:port/
  • http://host/api
  • http://host/api/

非法格式:

  • http://host (必须带 /
  • http://host:port (必须带 /

二、代理路径匹配规则

1. 基础匹配原则

nginx
location / {
    proxy_pass http://backend:8080;
}
  • 访问 / → 后端路径 /
  • 访问 /api/xx → 后端路径 /api/xx

2. 路径透传规则

location 规则 原始访问路径 透传后的路径
/ / (空)
/ /a a
/a/ /a/b/c?d b/c?d

三、URL 包含路径时的处理

1. 配置示例对比

场景1:URL 以 / 结尾

nginx
location / {
    proxy_pass http://backend:8080/;
}
  • 访问 /api/xx → 后端路径 /api/xx

场景2:URL 包含自定义路径

nginx
location /api/ {
    proxy_pass http://backend:8080/v1;
}
  • 访问 /api/xx → 后端路径 /v1xx (注意路径直接拼接)

场景3:路径规范配置

nginx
location /api/ {
    proxy_pass http://backend:8080/v1/;
}
  • 访问 /api/xx → 后端路径 /v1/xx (推荐写法)

2. 重要注意事项

proxy_pass 包含路径时,结尾的 / 应与 location 规则保持一致,否则会出现路径拼接异常。

四、正则匹配特殊处理

1. 禁止行为

nginx
# 错误示例(正则location中proxy_pass包含路径)
location ~* ^/api/ {
    proxy_pass http://backend/;  # 会报错
}

2. 正确解决方案

nginx
location ~* ^/api/ {
    proxy_pass http://backend;  # 仅保留host:port
}

五、URL 重写技巧

1. 基础重写示例

nginx
location ~* ^/api/ {
    rewrite ^/api/(.*) /?path=$1 break;
    proxy_pass http://backend:8080;
}
  • 访问 /api/a/b/c → 后端路径 /?path=a/b/c

2. 重写覆盖效果

nginx
location / {
    rewrite ^/api/(.*) /?path=$1 break;
    proxy_pass http://backend:8080/node/;
}
  • 重写规则会覆盖 proxy_pass 中的路径,最终访问 /?path=a/b/c

配置建议总结

  1. 普通 location 优先使用 location /path/ + proxy_pass http://host/ 格式
  2. 正则 location 必须使用无路径的 proxy_pass
  3. 路径拼接时注意结尾 / 的一致性
  4. 复杂路径转换优先考虑 rewrite 方案

测试脚本

以下是一个交互式 Bash 脚本,可以帮您分析输入的 Nginx locationproxy_pass 配置,预测实际代理的路径:

bash
#!/bin/bash
# Nginx proxy_pass 路径分析工具
# 使用方法:./proxy_analyzer.sh

echo -e "\033[1;36mNginx proxy_pass 路径分析器\033[0m"
echo "输入您的配置信息(按Ctrl+C退出)"

while true; do
  # 获取用户输入
  echo -e "\n\033[1;33m=== 新分析 ===\033[0m"
  read -p "请输入 location 匹配规则(例如:/api/):" location_rule
  read -p "请输入 proxy_pass 地址(例如:http://backend/):" proxy_pass_url
  read -p "请输入测试访问路径(例如:/api/users):" test_path

  # 解析 proxy_pass 组件
  if [[ $proxy_pass_url =~ (http[s]?://[^/]+)(/.*)? ]]; then
    backend_host=${BASH_REMATCH[1]}
    backend_path=${BASH_REMATCH[2]:-/}
  else
    echo -e "\033[1;31m错误:proxy_pass 格式无效\033[0m"
    continue
  fi

  # 处理 location 规则
  if [[ "$location_rule" == "/" ]]; then
    relative_path="$test_path"
  else
    relative_path=${test_path#$location_rule}
  fi

  # 判断路径处理类型
  if [[ "$proxy_pass_url" == */ ]]; then
    # 情况1:proxy_pass 以 / 结尾
    if [[ "$location_rule" == */ ]]; then
      final_path="${backend_path}${relative_path}"
    else
      final_path="${backend_path}${test_path#${location_rule%/}}"
    fi
  else
    # 情况2:proxy_pass 不以 / 结尾
    final_path="${backend_path%/}/${relative_path#/}"
  fi

  # 显示分析结果
  echo -e "\n\033[1;32m分析结果:\033[0m"
  echo -e "访问路径: \033[1;35m$test_path\033[0m"
  echo -e "实际代理到: \033[1;35m${backend_host}${final_path}\033[0m"

  # 显示处理逻辑
  echo -e "\n\033[1;34m处理逻辑:\033[0m"
  echo "1. location 规则: '$location_rule' 匹配后剩余路径: '$relative_path'"
  echo "2. proxy_pass 分解: 主机部分='$backend_host' 路径部分='$backend_path'"
  echo "3. 最终路径拼接: '${backend_path}' + '${relative_path}'"

  # 特殊案例提醒
  if [[ "$proxy_pass_url" != */ && "$location_rule" == */ ]]; then
    echo -e "\n\033[1;31m注意:proxy_pass 不以/结尾但 location 以/结尾,可能导致路径拼接异常!\033[0m"
  fi
done

使用示例

bash
$ ./proxy_analyzer.sh

Nginx proxy_path 路径分析器
输入您的配置信息(按Ctrl+C退出)

=== 新分析 ===
请输入 location 匹配规则(例如:/api/):/api/
请输入 proxy_pass 地址(例如:http://backend/):http://backend/v1/
请输入测试访问路径(例如:/api/users):/api/users/123

分析结果:
访问路径: /api/users/123
实际代理到: http://backend/v1/users/123

处理逻辑:
1. location 规则: '/api/' 匹配后剩余路径: 'users/123'
2. proxy_pass 分解: 主机部分='http://backend' 路径部分='/v1/'
3. 最终路径拼接: '/v1/' + 'users/123'

支持的配置类型

  1. 常规代理:
    • location /path/ + proxy_pass http://host/
    • location / + proxy_pass http://host:port
  2. 路径重写:
    • location /old/ + proxy_pass http://host/new/
  3. 特殊案例检测:
    • 自动识别路径拼接警告
    • 处理带查询参数的URL

实现原理

  1. 路径解析:
    • 使用 BASH_REMATCH 正则分组提取 proxy_pass 的主机和路径部分
    • 通过字符串操作处理 location 规则匹配
  2. 路径拼接逻辑:

  1. 边界情况处理:
    • 自动处理 location / 特殊情况
    • 保留原始查询参数(?后的内容)

可以将此脚本保存为 proxy_analyzer.sh,然后运行 chmod +x proxy_analyzer.sh 赋予执行权限。