我有一个 nginx 负载均衡器,用于处理对某些后端服务器的 http Web 请求。由于一些遗留原因,后端服务器无法更改,发出请求的客户端也无法更改。 http 请求包含参数。我有一组特殊字符(区分大小写)说 S = ["Q", "A", "B", "C"] 这些可以在特定参数中以任何顺序出现(让我们称之为“foo” ") 任意多次。我想用每个字符的特定预先指定字符串替换每个字符。假设 Q 被替换为 qx,A 被替换为 ay,B 被替换为 bz,C 被替换为 cz。举个例子
http:/localhost:5000/part?foo=QhelloAWorldBearthCLondon
这应该转变为:
http://localhost:5000/part?foo=qxhelloayWorldbzearthczLondon.
有没有办法通过 nginx 重写来做到这一点?我只想转换 foo 参数,而其他参数保持不变。尝试了递归方法,但在 10 次更新后被拒绝,因为 nginx 不允许更多更新。
Nginx maps 可以级联,这意味着问题可以分解为可管理的部分。
没有任何解决方案可以为您提供无限数量的转换,但下面的解决方案是可扩展的,因此您可以设置合理的上限。
例如:
map $arg_foo $newfoo1 {
~^(?<a1>.*)A(?<a2>.*)A(?<a3>.*)A(?<a4>.*)$ ${a1}ax${a2}ax${a3}ax${a4};
~^(?<a1>.*)A(?<a2>.*)A(?<a3>.*)$ ${a1}ax${a2}ax${a3};
~^(?<a1>.*)A(?<a2>.*)$ ${a1}ax${a2};
default $arg_foo;
}
map $newfoo1 $newfoo2 {
~^(?<b1>.*)B(?<b2>.*)B(?<b3>.*)B(?<b4>.*)$ ${b1}bx${b2}bx${b3}bx${b4};
~^(?<b1>.*)B(?<b2>.*)B(?<b3>.*)$ ${b1}bx${b2}bx${b3};
~^(?<b1>.*)B(?<b2>.*)$ ${b1}bx${b2};
default $newfoo1;
}
map $newfoo2 $newfoo3 {
~^(?<c1>.*)C(?<c2>.*)C(?<c3>.*)C(?<c4>.*)$ ${c1}cx${c2}cx${c3}cx${c4};
~^(?<c1>.*)C(?<c2>.*)C(?<c3>.*)$ ${c1}cx${c2}cx${c3};
~^(?<c1>.*)C(?<c2>.*)$ ${c1}cx${c2};
default $newfoo2;
}
map $newfoo3 $newfoo {
~^(?<d1>.*)Q(?<d2>.*)Q(?<d3>.*)Q(?<d4>.*)$ ${d1}qx${d2}qx${d3}qx${d4};
~^(?<d1>.*)Q(?<d2>.*)Q(?<d3>.*)$ ${d1}qx${d2}qx${d3};
~^(?<d1>.*)Q(?<d2>.*)$ ${d1}qx${d2};
default $newfoo3;
}
map $args $newargs {
default $args;
~^(?<e1>(?:.+&|)foo=)[^&]+(?<e2>&.*)?$ $e1$newfoo$e2;
}
server {
...
location /part {
rewrite ^ $uri?$newargs? break;
proxy_pass ...;
}
}
从底部开始,第五张地图将
foo=x
替换为 foo=y
,而不更改任何其他参数(如果有)。该映射的值可用于替换请求的 URL 中的参数。在上面的示例中,我们使用 rewrite...break.
其他映射均替换单个模式的一次或多次出现。在示例中,最大出现次数为 3,但可以轻松扩展到任何合理的数量。
用于映射和捕获的所有变量名称应该是唯一的,以避免无意中覆盖值。应避免数字捕获,因为在计算下一个正则表达式时该值会丢失。