I'm using the proxy function, but before the proxy, I want to use middleware to get the content in the body easily
let REQ_RAW = {}
server.use((req, res, next) => {
REQ_RAW = cloneDeep(req)
next()
})
server.use(middlewares) // I want to get the parsed content here, e.g. bodyParser
server.use((req, res, next) => {
req = REQ_RAW
next()
})
// server.use(other)
// Then use the `original request` to continue execution, such as proxy
// In fact, the req obtained here is the content processed by middlewares middleware
Hi @wll8, the approach you show above will not work as you expect. There are a few issues:
REQ_RAW would be shared between concurrent requests, so what you get later could be the request from another userreq does not mutate what the caller has, which is what calls the next middlewareCan I ask you why you want to "recover" the raw body?
If you have a really good reason which cannot be done in another way, here is one approach to this problem:
server.use((req, res, next) => {
const rawBody = req.body
bodyParser.json(req, res, (err) => {
req.body = rawBody
next(err)
})
})
Thank you. @wesleytodd
Can I ask you why you want to "recover" the raw body?
My original idea was:
How do I know the content of the request I forwarded to the proxy server? For example, file, body, query, even params.
I want to use the features of middleware to get these contents, because they are more convenient.
// Some requests are forwarded to the target server, which requires the original request
server.use(proxy('/api', {
target: 'http://www.example.org',
onProxyReq: (proxyReq, req, res) => {
// I want to parse the `req` through middleware here, the purpose is to make it easy for me to get what is forwarded
// But do not want to change the content of the `req`. Because the target server needs the original `req` content.
},
}))
// For requests that do not need to be forwarded, use middleware to easily obtain the content of the request
server.use(middlewares)
server.post('/file/upload', () => {})
I tried the following scenarios:
server.use([...middlewares, (req, res, next) => {
req.body // The `middlewares` are used to easily obtain the `body`
// But unfortunately, because `req` was parsed by the middleware, the proxy target server does not accept this request.
next()
}])
server.use(proxy())
server.use('*', server2)
server2.use([...middlewares, (req, res, next) => {
req.body // I thought the new `server2` would no longer affect` server`
next()
}])
server.use(proxy()) // Unfortunately, In fact, the `req` obtained here is the content processed by middlewares middleware
let REQ_RAW = {}
server.use((req, res, next) => {
REQ_RAW = cloneDeep(req)
next()
})
server.use(middlewares) // I want to get the parsed content here, e.g. bodyParser
server.use((req, res, next) => {
req = REQ_RAW
next()
})
server.use(proxy()) // Unfortunately, In fact, the `req` obtained here is the content processed by middlewares middleware
On gitter, no one replied to my questions T_T.
bodyParser.json(req, res, () => {})
I worry that some middleware does not provide callbacks.
If I understand correctly, your issue is that using the typical bodyParser middlewares mutates the request that passes through it? You want to send the intact request to your proxy, the request as it is before it passes through body-parser. But you also want to log/inspect the request on your server as well, so you want to serialize the request into something you can work with, like the body-parser middleware does.
I found some issues on other repos where others have had similar issues (working with body-parser and express proxy)
https://github.com/chimurai/http-proxy-middleware/issues/320
https://github.com/chimurai/http-proxy-middleware/issues/299
And finally here is an implementation which re-streams the request body to the proxy after it has been parsed by body-parser
https://github.com/http-party/node-http-proxy/blob/9bbe486c5efcc356fb4d189ef38eee275bbde345/examples/middleware/bodyDecoder-middleware.js
Thank you. I found a simple solution
server.use((req, res, next) => {
// Method 1
// middlewaresObj from jsonServer.defaults
middlewaresObj.jsonParser(req, res, () => {
console.log('req.body', req.body)
})
next()
// // Method 2
// const bodyParser = require('body-parser')
// bodyParser.json({
// limit: '10mb',
// extended: false
// })(req, res, () => {
// console.log('req.body', req.body)
// })
// next()
})
server.use(proxy())
If you need more methods, you can refer to these links: