使用 nginx 反向代理丢失 POST 请求正文

tdu*_*eon 8 nginx nginx-reverse-proxy

我使用 nginx 作为 http 服务的反向代理,使用如下配置:

location /jobexecutor/ {
        proxy_pass      http://jobexecutor:8080/jobexecutor/;
        proxy_set_header    Host $host;
        proxy_set_header    X-Real-IP $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto $scheme;
        proxy_redirect      off;
        proxy_connect_timeout   75s;
}
Run Code Online (Sandbox Code Playgroud)

GET 请求被代理到服务很好,但是当我使用 POST 时,请求被代理到服务 OK,但主体是空的。当直接发布到服务时,它工作正常。任何想法有什么问题?

mik*_*nik 5

您已找到解决方法,但我怀疑不是根本原因。

根据RFC7231,一个已知问题是 301 和 302 服务器响应通常会导致在遵循重定向时对 GET 请求不安全的请求方法的转换。

正常proxy_pass应该对客户端透明,因此听起来您的 Nginx 配置的其他部分在请求被代理之前首先进行了一些客户端重定向。

一旦确定发生这种情况,您可以重新配置 Nginx conf 以消除重定向,或者将 301/302 响应代码分别更改为 307/308,这在保持原始请求方法的同时进行重定向。

  • 这个。在我的情况下(在 OP 的情况下也很可能),我有“位置 /whatever/”,但将原始 POST 请求发送到 /whatever(没有尾部斜杠)。浏览器请求 /whatever,nginx 返回 301,浏览器自动在 /whatever/ 重试,但将请求方法更改为 GET。 (3认同)

tdu*_*eon 2

我终于找到了这个问题的答案。问题在于curl,因为当遵循重定向时,它希望将POST 转换为GET,但arg-X似乎强制它将其保留为GET,但主体丢失了。要获得预期的行为,您需要指定--post301或类似的参数(以及-L参数)。请参阅https://curl.haxx.se/docs/manpage.html#--post301