转发请求时需要两个功能, 一个是去掉 querystring 上特定的字段, 一个是替换掉一个字段的值.

参考两篇文章得到一个可用的方案,

https://itecnotes.com/server/...
https://zzyongx.github.io/blo...

主要的思路是通过正则, 对 $args 反复进行替换, 得到自己想要的结果,

upstream myhost {
  server myupstream.com:443;
}

# 强制 log 输出到 stdout
access_log /dev/stdout;
error_log /dev/stderr info;

server {
  listen 5555;

  location /my/api {

    # 目前接口都转发到该域名
    set $target_host "myupstream.com";
    # set $target_host REPLACED_HOST;

    set $target_data "REPLACED_DATA";
    # set $target_data "dev";

    # 正则处理的不是数据结构, 各种组合需要手动遍历

    # 去掉后边的 extraKey
    if ( $args ~* ^(.*)&extraKey=[\w\d]+(.*)$ ) {
      set $args $1$2;
    }
    # 去掉开头的 extraKey
    if ( $args ~* ^extraKey=[\w\d]+(.*)$ ) {
      set $args $2;
    }
    # 清除 myData
    if ( $args ~* ^(.*)&myData=\w+(.*)$ ) {
      set $args $1$2;
    }
    # 清除开头的 myData
    if ( $args ~* ^myData=\w+(.*)$ ) {
      set $args $1;
    }

    # 清除后设置一个指定一个参数
    set $arg_myData "$target_data";
    
    proxy_set_header Host $target_host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # proxy_set_header X-Real-IP $remote_addr;
    proxy_pass_request_headers on;

    # HTTP 转 HTTPS 用
    proxy_ssl_server_name on;

    set $args "$args&myData=$arg_myData";

    # 调试用
    # return 200 "$target_host/api$uri$is_args$args&myData=$arg_myData";
    proxy_pass https://myhost/api$uri$is_args$args;
  }
}

注意 $arg_myData 虽然是从 querystring 解析出来的 field, 但是修改了只会增加, 而不是替换. 直接增加可能出现两个 myData 的请求, 不能保证服务器解析和处理都是对的. 所以应该是先清除, 再自己加上.

功能不难, 调试时报错不够透明, 一搬用 return 200 "content"; 强行返回查看. 其他看不到的中间过程只能尽量抓出来看了.


题叶
17.3k 声望2.6k 粉丝

Calcit 语言作者