我遇到了一个奇怪的问题,我不确定这是配置问题还是 nginx 中的错误。我的设置是一个 nginx 反向代理,它有 Apache2 后端服务器。负载平衡器非常基础,类似于来自 wiki 的示例,例如简化:
http {
upstream myproject {
server 127.0.0.1:8000;
}
server {
listen 80;
location / {
proxy_pass http://myproject;
}
}
}
现在,当我尝试在 Apache 中请求目录时,如果 URL 末尾没有斜杠,就会出现问题。例如,客户端请求:
http://apache.myserver.com/somedirectory
Apache 将回复 HTTP 302,以将客户端重定向到
http://apache.myserver.com/somedirectory/
请注意,url 末尾有一个斜杠,表示它是一个目录。还请注意,Apache 很“聪明”,在重定向标头中使用传入请求的主机名。到目前为止一切正常。但是,当使用具有负载平衡的 nginx 时,此 301 会发送到客户端,而不会将 nginx 上游名称转换回实际的服务器/域。因此,客户端将收到以下内容:
GET http://nginx.myserver.com/somedirectory
HTTP 301 Moved Permanently
...
Location: http://myproject:8000/somedirectory/
这myproject
是 nginx 上游后端的名称。它不是客户端可以解析的实际主机。在我看来,客户端应该被重定向到
http://nginx.myserver.com/somedirectory/
即,上游后端的名称应该在响应标头中被替换。这是 nginx 中的错误还是我做错了什么?
答案1
事实证明,nginx 有很多代理重定向处理此类问题的选项。我最终使用了类似这样的方法:
location / {
proxy_pass http://myproject;
proxy_set_header Host myproject;
proxy_redirect http://myproject/ $scheme://$host/;
proxy_redirect http://myproject:8000/ $scheme://$host/;
}
这基本上用 $host 替换上游名称并删除端口。这在我的情况下有效,因为我在 HTTP/HTTPS 的默认端口上托管 nginx。如果 nginx 在非默认端口上运行,则需要类似以下内容:
proxy_redirect http://myproject/ $scheme://$host:$server_port/;
proxy_redirect http://myproject:8000/ $scheme://$host:$server_port/;