You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Nginx中基于Cookie和Header的Map配置重复?

如何避免重复编写Nginx的map配置?

我现在有两套逻辑完全一致的Nginx map配置:一套基于Cookie值,另一套基于请求头,如下所示:

基于Cookie的map配置

map $cookie_version $version_host {
    default 172.17.0.1:8001;
    2.65.1 172.17.0.1:8001;
    2.65.2 172.17.0.1:8003;
}

基于请求头的map配置

map $http_app_version $version_api_host {
    default 172.17.0.1:8001;
    2.65.1 172.17.0.1:8001;
    2.65.2 172.17.0.1:8003;
}

我的server块配置如下:

server {
    listen 443 ssl;
    ssl_certificate         /etc/ssl/nexello.crt;
    ssl_certificate_key     /etc/ssl/nexello.key;
    server_name             _;
    proxy_set_header Host             $host;
    proxy_set_header X-FORWARDED-FOR  $remote_addr;

    charset utf-8;

    location / {
        # Web端访问
        # 用Cookie而非请求头是因为请求到达这里时,JavaScript还没来得及设置请求头
        if ($cookie_token) {
            proxy_pass https://$version_host;
        }

        # API端访问
        # 这里用请求头是因为调用API的客户端可以完全控制请求头
        if ($http_authorization) {
            proxy_pass https://$version_api_host;
        }

        # 未授权跳转
        # 如果既没有请求头也没有Cookie,说明没有访问令牌,跳转到认证服务
        proxy_pass https://172.17.0.1:7001;
    }
}

请问有没有办法避免重复编写这两套逻辑相同的map配置?


解决方案1:统一版本变量,复用单个map

先把Cookie和请求头的版本值合并成一个统一变量,再基于这个变量编写一套map即可:

  1. 定义统一版本变量
    可以用map或set指令实现,这里推荐map的方式(避免if指令的潜在问题):
# 优先取请求头的版本,没有则取Cookie的版本,都没有则为空
map "" $unified_version {
    default "";
    $http_app_version $http_app_version;
    $cookie_version $cookie_version;
}
  1. 编写单套map配置
    基于统一变量定义映射规则:
map $unified_version $target_host {
    default 172.17.0.1:8001;
    2.65.1 172.17.0.1:8001;
    2.65.2 172.17.0.1:8003;
}
  1. 修改server块逻辑
    直接在不同场景下使用统一的$target_host:
server {
    listen 443 ssl;
    ssl_certificate         /etc/ssl/nexello.crt;
    ssl_certificate_key     /etc/ssl/nexello.key;
    server_name             _;
    proxy_set_header Host             $host;
    proxy_set_header X-FORWARDED-FOR  $remote_addr;

    charset utf-8;

    location / {
        if ($cookie_token) {
            proxy_pass https://$target_host;
        }

        if ($http_authorization) {
            proxy_pass https://$target_host;
        }

        proxy_pass https://172.17.0.1:7001;
    }
}

解决方案2:用include引入外部规则片段

如果需要保留两个独立的map变量,但不想重复写映射规则,可以把规则单独抽成外部文件:

  1. 创建规则文件
    新建/etc/nginx/conf.d/version-rules.conf,内容为:
default 172.17.0.1:8001;
2.65.1 172.17.0.1:8001;
2.65.2 172.17.0.1:8003;
  1. 在map中引入规则
    修改原有的两个map配置,通过include引入外部规则:
map $cookie_version $version_host {
    include /etc/nginx/conf.d/version-rules.conf;
}

map $http_app_version $version_api_host {
    include /etc/nginx/conf.d/version-rules.conf;
}

这种方式无需修改server块的原有逻辑,只需要维护外部规则文件即可。

内容的提问来源于stack exchange,提问作者Mathias Hillmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:12:49