当前位置: 首页 > 知识库问答 >
问题:

如何将Nginx中的POST/PUT/...重新路由到内部服务?

吕征
2023-03-14

我有一个安装了nginx的服务器(ubuntu 20.04内核)。在同一台服务器上,我在端口8080上有一个正在运行的Spring Boot Web(2.3.3.RELEASE)服务。

我想从外部访问Spring Boot Web服务中的资源,例如:。http://server/api/users访问http://localhost/api/users并将该响应返回给客户端

我在nginx中配置了以下规则:

location /api {
    proxy_pass http://localhost:8080;
}

这对于GET请求很好,但对于POST或PUT则不行。对客户端的第一个响应是状态代码为301的响应:永久移动,根据HTTP规范,客户端应将HTTP方法更改为GET或HEAD。客户端在第一次响应后自动更改方法,如位于/var/log/nginx/access的nginx日志文件所示。日志:

192.168.0.1 - - [14/Oct/2020:11:23:56 +0100] "POST /api/users?key=key HTTP/1.1" 301 162 "-" "PostmanRuntime/7.26.5"
192.168.0.1 - - [14/Oct/2020:11:23:56 +0100] "GET /api/users?key=key HTTP/1.1" 200 93 "http://server/api/users?key=key" "PostmanRuntime/7.26.5"
192.168.0.1 - - [14/Oct/2020:11:23:59 +0100] "PUT /api/users/1/deleted?key=key&deleted=false HTTP/1.1" 301 162 "-" "PostmanRuntime/7.26.5"
192.168.0.1 - - [14/Oct/2020:11:23:59 +0100] "GET /api/users/1/deleted?key=key&deleted=false HTTP/1.1" 405 141 "http://server/api/users/1/deleted?key=key&deleted=false" "PostmanRuntime/7.26.5"

来自PUT请求的GET请求失败,返回405,因为路径“/api/users/{id}/deleted”没有映射的GET。我尝试在“location/api{..}”中添加和修改许多不同的配置例如:

location /api {
  proxy_pass      http://localhost:8080;
  proxy_redirect  http://localhost:8080/ /; # I tried "../api /", ".../api/ /", ".../ /api" 
  proxy_read_timeout 60s;

  proxy_set_header          Host            $host;
  proxy_set_header          X-Real-IP       $remote_addr;
  proxy_set_header          X-Forwarded-For $proxy_add_x_forwarded_for;
}

serverfault中建议(如何让nginx通过重写转发HTTP POST请求?)

我在trac上发现了完全相同的问题。nginx公司。com,但该配置也不起作用:

location /api { # "/api" and "/api/" doesn't work
    proxy_pass ​http://localhost:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

我现在完全不知道还有什么我应该试着让它工作。

---编辑:在@ti7和@Amplelarius的帮助下,现在的工作解决方案是:

NGINX位置条目:

location /api {
    proxy_pass http://localhost:8080;
    proxy_redirect off;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Port  $server_port;
}

并且在Spring Boot Service的application.properties中没有进行任何更改,因此这些设置都不会对这种情况执行任何操作:

server.use-forward-headers=true
server.forward-headers-strategy=native
server.forward-headers-strategy=framework
server.forward-headers-strategy=none

共有2个答案

公羊光明
2023-03-14

这可能是因为后端服务器认为请求是http,并将其重定向到https。尝试将此添加到您的位置块中:

proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port  $server_port;

它让您的后端服务器知道,请求实际上是通过https发出的,但tls会进一步终止(在大多数情况下,您必须将代理服务器列入白名单才能使其工作)。

根据这个答案,你可以这样做application.properties:

server.use-forward-headers=true
彭鹭洋
2023-03-14

最近,我一直在使用带有nginx前端的出色GUnicorn WSGI服务器进行大量工作。

部署文档建议禁用proxy_redirectproxy_passHost头集,这可能是您的麻烦的来源!

这对于处理POSTGET请求非常有效,尽管使用了完全不同的Web服务器。

location @proxy_to_app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    # we don't want nginx trying to do something clever with
    # redirects, we set the Host: header above already.
    proxy_redirect off;
    proxy_pass http://app_server;
}
 类似资料:
  • 我有一个安装了nginx的服务器(Ubuntu20.04核心)。在同一台服务器上,我在端口8080上有一个正在运行的Spring Boot Web(2.3.3.Release)服务。 我想从Spring Boot Web服务外部访问资源,例如http://server/api/users,以访问http://localhost/api/users,并将响应返回给客户机。 我在nginx中配置了以下

  • 问题内容: 因此,我有一个登录页面(’/’)。此页面上是带有提交按钮的用户名和密码的登录表单。我有加载页面的app.get和一个app.post来接收表单的参数。但是,我的目的是要有一个app.post(’/ login’,function(req,res){// logic}); 没有/ login路由或页面要加载,这只会容纳登录本身的逻辑(验证用户名等)。是否有一种简单的方法来使帖子从’/’重

  • 我对Java服务器端编程还不熟悉,我的问题基本上是使用Servlets(低级别,不使用spring mvc等)开始一个起点,然后从node开始构建。js后台,其中路由定义将以函数(,等),函数将在http方法之一(GET、post、PUT、DELETE)的参数中接收和。 如果有人可以帮助我,从一个servlet类中的路由(比如说)开始定义方法,这个servlet类映射到http方法,同时在其参数中

  • 我想让流量如下所示: 外部客户端https请求(例如。https://my-app-out-side-cluster.com) - 我遵循这篇文章来配置我的入口和外部流量,但是,由于我在集群外的服务是http,所以在使用https发出请求时,我会遇到SSL错误。但是,将请求更改为http是可行的,这是不需要的。 我的问题是,有没有办法 在入口中终止SSL(使用入口控制器) 是否将流量重定向到群集外

  • 问题内容: 我正在使用express (最新)和以下代码: POST重定向到GET,但PUT重定向到PUT。是否可以将PUT重定向到GET(与POST相同)? 问题答案: 在详细讨论之前,下面是解决问题的一种方法: 默认情况下,Express使用HTTP代码302进行重定向。根据HTTP规范,这可以防止POST / PUT请求被重定向为POST / PUT请求,并解释了您在代码中观察到的内容: 如