除GET之外的代理请求都与NestJS和http-proxy-middleware一起挂起

示例代码可在https://github.com/baumgarb/reverse-proxy-demo上找到:README.md解释了如果您克隆存储库,如何重现该问题。

我有一个API网关和一个返回服务的下游服务(TodosAPI)。客户端通过API网关访问下游服务。

API网关正在利用http-proxy-middleware包来代理请求。有两种实现,第二种不起作用:

1。 main.ts中的全局中间件,它在路径/ api / v1 / ...上启动

这种方法可以很好地工作,并且无论使用哪种http方法(GET,PUT等),它都会代理对下游服务的所有请求。

import * as proxy from 'http-proxy-middleware';

app.use(
  '/api/v1/todos-api',proxy({
    target: 'http://localhost:8090/api',pathRewrite: {
      '/api/v1/todos-api': ''
    },secure: false,onProxyReq: (proxyReq,req,res) => {
      console.log(
        `[Global Functional Middlware]: Proxying ${req.method} request originally made to '${req.originalUrl}'...`
      );
    }
  })
);

2。已在应用模块中注册的nestMiddleware,该模块会在/ api / v2 / ...路径上启动

此方法对GET请求有效,但是其他http方法(如PUT)保持“挂起”状态,并且客户端上从未收到任何响应。问题似乎是从不调用下游服务中的控制器。

import * as proxy from 'http-proxy-middleware';

export class ReverseProxyMiddleware implements nestMiddleware {
  private proxy = proxy({
    target: 'http://localhost:8090/api',pathRewrite: {
      '/api/v2/todos-api': ''
    },res) => {
      console.log(
        `[nestMiddleware]: Proxying ${req.method} request originally made to '${req.originalUrl}'...`
      );
    }
  });

  use(req: Request,res: Response,next: () => void) {
    this.proxy(req,res,next);
  }
}

该中间件注册如下:

@Module({
  imports: [],controllers: [AppController],providers: [AppService]
})
export class AppModule implements nestModule {
  configure(consumer: import('@nestjs/common').MiddlewareConsumer) {
    consumer
      .apply(ReverseProxyMiddleware)
      .forRoutes({ path: 'v2/todos-api',method: RequestMethod.ALL });
  }
}
  • 运行curl -X PUT -H "Content-Type: application/json" -d "{\"id\": 1,\"userId\": 1,\"title\": \"delectus aut autem - v1\",\"completed\": true}" http://localhost:8080/api/v1/todos-api/1效果很好
  • 运行curl -X PUT -H "Content-Type: application/json" -d "{\"id\": 1,\"title\": \"delectus aut autem - v2\",\"completed\": true}" http://localhost:8080/api/v2/todos-api/1时遇到问题,即永远不会调用下游服务中的控制器

nestMiddleware正在代理请求(我可以看到一条日志行显示[nestMiddleware]: Proxying PUT request originally made to '/api/v2/todos-api/1'...),下游服务接收到该请求(我可以从日志记录中看到)。但是下游服务不会调用控制器/动作,并且最终永远不会返回。

有人知道我在做什么错吗?提前非常感谢!

mfpaaa 回答:除GET之外的代理请求都与NestJS和http-proxy-middleware一起挂起

在创建Nest Application时设置bodyParser: false只是解决了我们正在代理的端点的问题,这将导致其他端点(例如JWT localAuth)失败,因为它们需要解析正文。

解决方案是按照this anwser中的描述创建一个中间件,以针对要代理的端点禁用bodyParser,并为其余代理启用它。

,

我终于找到了问题所在。它似乎与主体解析器有关。如果我更改API网关以关闭主体解析器,则请求将成功转发。

因此解决方案是替换

const app = await NestFactory.create(AppModule);

使用

const app = await NestFactory.create(AppModule,{ bodyParser: false });

我还在实现修补程序的Git存储库中创建了一个分支issue-fixed

本文链接:https://www.f2er.com/3153512.html

大家都在问