Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Express代理中间件问题与解决方案 #50

Closed
wangduanduan opened this issue Feb 21, 2019 · 0 comments
Closed

Express代理中间件问题与解决方案 #50

wangduanduan opened this issue Feb 21, 2019 · 0 comments

Comments

@wangduanduan
Copy link
Owner

前后端分离应用的架构

在前后端分离架构中,为了避免跨域以及暴露内部服务地址。一般来说,我会在Express这层中加入一个反向代理。

所有向后端服务访问的请求,都通过代理转发到内部的各个服务。

这个反向代理服务器,做起来很简单。用http-proxy-middleware这个模块,几行代码就可以搞定。

// app.js
Object.keys(proxyTable).forEach(function (context) {
  app.use(proxyMiddleware(context, proxyTable[context]))
})

http-proxy-middleware实际上是对于node-http-proxy的更加简便的封装。node-http-proxy是http-proxy-middleware的底层包,如果node-http-proxy有问题,那么这个问题就会影响到http-proxy-middleware这个包。

最近的bug

http-proxy-middleware最近有个问题,请求体在被代理转发前,如果请求体被解析了。那么后端服务将会收不到请求结束的消息,从浏览器的网络面板可以看出,一个请求一直在pending状态。

Cannot proxy after parsing body #299, 实际上这个问题在node-http-proxy也被提出过,而且处于open状态。POST fails/hangs examples to restream also not working #1279

目前这个bug还是处于open状态,但是还是有解决方案的。就是将请求体解析的中间件挂载在代理之后

下面的代码,express.json()会对json格式的请求体进行解析。方案1在代理前就进行body解析,所有格式是json的请求体都会被解析。

但是有些走代理的请求,如果我们并不关心请求体的内容是什么,实际上我们可以不解析那些走代理的请求。所以,可以先挂载代理中间件,然后挂载请求体解析中间件,最后挂载内部的一些接口服务。

// 方案1 bad
app.use(express.json())
Object.keys(proxyTable).forEach(function (context) {
  app.use(proxyMiddleware(context, proxyTable[context]))
})
app.use('/api', (req, res, next)=> {

})

// 方案2 good
Object.keys(proxyTable).forEach(function (context) {
  app.use(proxyMiddleware(context, proxyTable[context]))
})
app.use(express.json())
app.use('/api', (req, res, next)=> {

})

总结

经过这个问题,我对Express中间件的挂载顺序有了更加深刻的认识。

同时,在使用第三方包的过程中,如果该包bug,那么也需要自行找出合适的解决方案。而这个能力,往往就是高手与新手的区别。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant