Nginx 通过自定义 header 进行 转发

背景

  • 后台接口较多
  • 版本更新较快,如 IOS 提交 App Store 审核 时间不固定
  • 需要支持线上环境多个app版本并存

解决办法

App 在发送 HTTP(S) 请求时, 增加自定义请求头,通过配置 Nginx 匹配请求头 verison 来转发到 预发布环境(预发布为最新代码),App Store 审核通过后将 Nginx配置 去掉即可。

核心:客户端自定义的 http header,在Nginx的配置文件里能直接读取到。

条件:header必须用减号“-”分隔单词,Nginx里面会转换为对应的下划线“_”连接的小写单词。

location / {
        if ($http_version = "v1"){
            proxy_pass http://api_30010;
        }
        if ($http_version = "v2"){
            proxy_pass http://api_30020;
        }

        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Forwarded-Host $server_name;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

参数配置说明:

  • underscores_in_headers on, Nginx 是支持读取 非Nginx标准的用户自定义header 的,但是需要在 http 或者 server 下开启 header的下划线支持:
  • 比如我们自定义 header 为 verison,获取该 header 时需要这样 $http_version (一律采用小写,而且前面多了个http_)
  • 如果需要把自定义header传递到下一个 Nginx,
  1. 如果是在nginx中自定义采用 proxy_set_header X_CUSTOM_HEADER $http_host;
  2. 如果是在用户请求时自定义的header,例如 curl --head -H "version:v1" https://api.xyzla.com/hello ,则需要通过 proxy_pass_header X_CUSTOM_HEADER 来传递。

注意: if ( 之间留有一个空格,否则会报错 nginx: [emerg] unknown directive "if($http_version