Nginx代理:是否可以在URL中添加静态参数?

25
5个回答

33
location = /oneapi {
  set $args $args&apiKey=tiger;
  proxy_pass https://api.somewhere.com;
}

9
如果 $args 是空的,你就将 $args 设置为 ?&apiKey=tiger。这不正确。 - Jack
事实上,我验证了你的答案太快了,编辑后的解决方案起作用了。在问题中$args不为空=> ?field=22&apiKey=tiger - user1475269
3
在使用 location /somepath 块(没有等号)时,似乎无法起作用。我不得不在相同的位置使用 rewrite ^(.*)$ $1?$args&myParam=value break; 来代替。 - nerdherd
很棒的解决方案,但如果您希望在$args为空时它能正常工作,请查看我的解决方案。 - warch
这不是最干净的方式。请看看我的。 - RammusXu

16

如果$args为空,则其他答案无效。

即使$args为空,这种方法也有效。

location /oneapi {
  set $delimeter "";

  if ($is_args) {
    set $delimeter "&";
  }

  set $args "$args${delimeter}apiKey=tiger";

  proxy_pass https://api.somewhere.com/;
}

1
非常感谢 :D :D - abdoutelb
这不是最干净的方式。请看看我的。 - RammusXu

4

GitHub Gist https://gist.github.com/anjia0532/da4a17f848468de5a374c860b17607e7

(这是指向 GitHub Gist 的链接)
    #set $token "?"; # deprecated

    set $token ""; # declar token is ""(empty str) for original request without args,because $is_args concat any var will be `?`

    if ($is_args) { # if the request has args update token to "&"
        set $token "&";
    }

    location /test {
        set $args "${args}${token}k1=v1&k2=v2"; # update original append custom params with $token
        # if no args $is_args is empty str,else it's "?"
        # http is scheme
        # service is upstream server
        #proxy_pass http://service/$uri$is_args$args; # deprecated remove `/`
        proxy_pass http://service$uri$is_args$args; # proxy pass
    }

    #http://localhost/test?foo=bar ==> http://service/test?foo=bar&k1=v1&k2=v2

    #http://localhost/test/ ==> http://service/test?k1=v1&k2=v2

1
如果您解释代码及其原因,答案会更好。 - ADyson
接近了,但是当 $args 为空时,http://localhost/test/ 实际上会重定向到 http://service/test??k1=v1&k2=v2(有两个问号),这似乎是由于 nginx 在将 $is_args 与另一个字符串连接时将其转换为 ?,即使为空也是如此。如果从最终语句中删除 $is_args,则当 $args 不为空时会导致前一个标记缺失。 - Mahn
如果 $args 是空的,那么 $token 就是 ?,所以 set $args "${args}${token}k1=v1&k2=v2" 会得到一个空字符串+?+自定义参数。如果 $args 不为空,那么 $token 就是 &L8 代码就是 ?old args+&+自定义参数。 - AnJia
@Mahn nginx的文档 http://nginx.org/en/docs/http/ngx_http_core_module.html#var_is_args 中提到:如果请求行有参数,则为?,否则为空字符串。 - AnJia
@AnJia,我理解你的意图,但在我的实际测试中,nginx文档似乎是错误的,当与另一个字符串连接时,$is_args永远不为空。如果您愿意,请自行测试。 - Mahn
显示剩余3条评论

3
以下是关于如何在nginx中添加参数的一种方法,即使不知道原始URL是否有参数(即需要考虑&),也可以实现这个功能:
location /oneapi {
    set $pretoken "";
    set $posttoken "?";

    if ($is_args) {
        set $pretoken "?";
        set $posttoken "&";
    }

    # Replace apiKey=tiger with your variable here
    set $args "${pretoken}${args}${posttoken}apiKey=tiger"; 

    # Optional: replace proxy_pass with return 302 for redirects
    proxy_pass https://api.somewhere.com$uri$args; 
}

1

对于来到这里的人。感谢https://serverfault.com/questions/912090/how-to-add-parameter-to-nginx-query-string-during-redirect

2021年最干净的方法是:

rewrite ^ https://api.somewhere.com$uri?apiKey=tiger permanent;

如果替换字符串包括新请求参数,则以前的请求参数将在它们之后追加。
代理传递方式。

upstream api {
    server api.somewhere.com;
}

location /oneapi {
    rewrite ^/oneapi/?(.*) /$1?apiKey=tiger break;
    proxy_pass https://api$uri$is_args$args;
}

重定向和代理是两个不同的概念。尝试在谷歌上搜索“重定向 vs 代理”。 - Lukman
@Lukman 它们可以一起使用。尝试谷歌搜索“rewrite proxy_pass together”。 - RammusXu
这是在查询参数方面正确且最灵活的方式。 - diswutz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接