避免nginx解码proxy_pass上的查询参数(相当于AllowEncodedSlashes NoDecode)

我使用nginx作为一个负载balencer在几个tomcats之前。 在我的传入请求中,我编码了查询参数。 但是当请求到达tomcat时,参数被解码:

传入的请求到nginx:

curl -i "http://server/1.1/json/T;cID=1234;pID=1200;rF=http%3A%2F%2Fwww.google.com%2F" 

传入的请求到tomcat:

 curl -i "http://server/1.1/json/T;cID=1234;pID=1200;rF=http:/www.google.com/" 

我不希望我的请求参数被转换,因为在那种情况下,我的tomcat会抛出405错误。

我的nginxconfiguration如下:

 upstream tracking { server front-01.server.com:8080; server front-02.server.com:8080; server front-03.server.com:8080; server front-04.server.com:8080; } server { listen 80; server_name tracking.server.com; access_log /var/log/nginx/tracking-access.log; error_log /var/log/nginx/tracking-error.log; location / { proxy_pass http://tracking/webapp; } } 

在我目前的Apache负载平衡器configuration中,我有AllowEncodedSlashes指令,保留我的编码参数:

 AllowEncodedSlashes NoDecode 

我需要从apache移动到nginx。

我的问题与此问题完全相反: 避免nginx在proxy_pass上转义查询参数

我终于找到了解决办法:我需要传递$request_uri参数 :

 location / { proxy_pass http://tracking/webapp$request_uri; } 

这样,在原始请求中编码的字符将不会被解码,即将被原样传递给代理服务器。

Jean的答案是好的,但是这不适用于sublocations。 在这种情况下,更一般的答案是:

 location /path/ { if ($request_uri ~* "/path/(.*)") { proxy_pass http://tracking/webapp/$1; } } 

Nginx的proxy_pass指令有一个记录的选项

如果有必要以未处理的形式传送URI,则应使用伪指令proxy_pass, 而不使用URI部分

 location /some/path/ { proxy_pass http://127.0.0.1; } 

所以在你的情况下,可能是这样的。 不要担心请求URI,它将被传递到上游服务器

 location / { proxy_pass http://tracking; } 

希望能帮助到你。

在某些情况下,问题不在nginx端 – 您必须将Tomcat连接器上的uri编码设置为UTF-8。