Jea*_*ana 23 reverse-proxy load-balancing nginx
我使用nginx作为几个tomcats前面的负载balencer.在我的传入请求中,我编码了查询参数.但是当请求到达tomcat时,参数被解码:
传入nginx的请求:
curl -i "http://server/1.1/json/T;cID=1234;pID=1200;rF=http%3A%2F%2Fwww.google.com%2F"
Run Code Online (Sandbox Code Playgroud)
传入tomcat的请求:
curl -i "http://server/1.1/json/T;cID=1234;pID=1200;rF=http:/www.google.com/"
Run Code Online (Sandbox Code Playgroud)
我不希望我的请求参数被转换,因为在那种情况下我的tomcat会抛出405错误.
我的nginx配置如下:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在我当前的apache负载均衡器配置中,我有AllowEncodedSlashes指令来保留我的编码参数:
AllowEncodedSlashes NoDecode
Run Code Online (Sandbox Code Playgroud)
我需要从apache转移到nginx.
我的问题与这个问题完全相反:避免nginx在proxy_pass上转义查询参数
Jea*_*ana 44
我终于找到了解决方案:我需要传递$request_uri参数:
location / {
proxy_pass http://tracking/webapp$request_uri;
}
Run Code Online (Sandbox Code Playgroud)
这样,原始请求中编码的字符将不会被解码,即将按原样传递给代理服务器.
use*_*062 13
Jean的答案很好,但它不适用于子位置.在这种情况下,更通用的答案是:
location /path/ {
if ($request_uri ~* "/path/(.*)") {
proxy_pass http://tracking/webapp/$1;
}
}
Run Code Online (Sandbox Code Playgroud)
Cas*_*sey 10
Nginx proxy_pass指令有一个记录的选项
如果需要以未处理的形式传输URI,则应使用指令proxy_pass 而不使用URI部分:
location /some/path/ {
proxy_pass http://127.0.0.1;
}
Run Code Online (Sandbox Code Playgroud)
所以在你的情况下它可能是这样的.不要担心请求URI会被传递给上游服务器
location / {
proxy_pass http://tracking;
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
请注意,URL解码(在Nginx文档中通常称为$uri“规范化”)发生在后端IFF之前:
要么在proxy_pass其内部指定了任何URI ,即使仅是尾部的斜杠本身,
或者,在处理过程中,例如,通过更改URI rewrite。
这两个条件都在http://nginx.org/r/proxy_pass(着重强调)中明确记录:
如果使用URI
proxy_pass指定了伪指令,那么当请求传递到服务器时,与该位置匹配的规范化请求URI 的一部分将由伪指令中指定的URI替换。
如果
proxy_pass指定为不带URI,则将请求URI以与原始请求处理时客户端发送的格式相同的形式传递给服务器,或者在处理更改的URI 时传递完整的规范化请求URI。
解决方案取决于您是否需要更改前端和后端之间的URL。
如果不需要更改URI:
# map `/foo` to `/foo`:
location /foo {
proxy_pass http://localhost:8080; # no URI -- not even just a slash
}
Run Code Online (Sandbox Code Playgroud)否则,如果您确实需要在后端/api与前端交换或映射/app,则可以从$request_uri变量获取原始URI,然后对变量使用rewrite指令,$uri类似于DFA(BTW,如果需要更多rewriteDFA操作,请查看mdoc.su)。请注意,return 400如果有人试图绕过您的第二个重写规则,则该部分是必需的,因为它不匹配//api/。
# map `/api` to `/app`:
location /foo {
rewrite ^ $request_uri; # get original URI
rewrite ^/api(/.*) /app$1 break; # drop /api, put /app
return 400; # if the second rewrite won't match
proxy_pass http://localhost:8080$uri;
}
Run Code Online (Sandbox Code Playgroud)如果您只想为后端添加前缀,则可以立即使用$request_uri变量:
# add `/webapp` to the backend:
location / {
proxy_pass http://localhost:8080/webapp$request_uri;
}
Run Code Online (Sandbox Code Playgroud)您可能还想看看一个相关的答案,该答案显示了一些类似于上述代码的测试运行。
| 归档时间: |
|
| 查看次数: |
26430 次 |
| 最近记录: |