Nginx 通过请求方法代理

Bre*_*ker 26 http nginx proxy

是否可能/如何根据请求方法(即 GET/POST)配置 Nginx 位置块以代理到不同的后端?

原因是,我目前正在处理 2 个不同 URL 的 2 种方法(一个通过 http 代理,另一个通过 fcgi),并试图使其更加“REST”,因此,理想情况下希望获取资源以返回列表,而 POST 到相同的资源应该添加到列表中。

Jas*_*son 37

我不使用此配置,而是基于此处示例

location /service  {
  if ($request_method = POST ) {
    fastcgi_pass 127.0.0.1:1234;
  }

  if ($request_method = GET ) {
     alias /path/to/files;
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您编写自己的应用程序,您还可以考虑检查其中的 GET/POST,并发送X-Accel-Redirect标头以将文件传输到 nginx。

  • 请注意,Nginx 文档通常不鼓励使用 `if`:https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ (3认同)

vog*_*vog 28

尽管您可以使用 实现这一点if但 Nginx 文档通常不鼓励if这样做,因为与其他指令不能很好地配合。例如,假设 GET 应该对所有人开放,而 POST 仅适用于经过身份验证的用户,使用 HTTP 基本身份验证。这将需要ifauth_basic无法正常工作的结合使用。

这是一个无需if. 诀窍是使用“GET”和“POST”作为上游名称的一部分,因此可以通过变量替换来解决这些问题:

http {
  upstream other_GET {
    server ...;
  }
  upstream other_POST {
    server ...;
  }
  server {
    location /service {
      proxy_pass http://other_$request_method;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

要将其与 HTTP 基本身份验证相结合,除了 GET 之外的所有内容,只需添加一个limit_except块:

  ...
    location /service {
      proxy_pass http://other_$request_method;
      limit_except GET {
        auth_basic ...;
      }
    }
  ...
Run Code Online (Sandbox Code Playgroud)


小智 7

我无法从@timmmmmy 那里得到答案,但它向我指出了地图文档,这对我有用:

map $request_method $upstream_location {
   PUT     example.com:8081;
   POST    example.com:8081;
   PATCH   example.com:8081;
   default example.com:8082;
}
server {
   location / {
      proxy_pass https://$upstream_location;
   }
}
Run Code Online (Sandbox Code Playgroud)