NodeJS - 编辑和代理 multipart/form-data 请求
NodeJS - Edit and proxy a multipart/form-data request
我有一个微服务,它代理每个请求并向其添加一个字段。对于普通请求,这非常简单,只需在 request.body 中添加字段并正确设置 headers 但对于 multipart/form-data 请求我有麻烦了几天以来,因为如果我在 request.body 中添加一个字段,它就会消失。
const router = express()
const routes = require('~/routes')
const passport = require('passport')
const proxy = require('http-proxy-middleware')
router.use(passport.initialize())
require('./modules/passport-jwt')(passport)
router.use('/', routes)
router.use(
'/account',
passport.authenticate('jwt', { session: false }),
proxy({
target: process.env.ACCOUNT_SERVICE,
pathRewrite: { '/account': '/' },
onProxyReq: restream
})
)
const restream = async function (proxyReq, req, res, options) {
if (req.user) {
if (
req.headers['content-type'] &&
req.headers['content-type'].match(/^multipart\/form-data/)
) {
req.body.reqUser = req.user
} else {
const requestBody = JSON.stringify({ ...req.body, reqUser: req.user })
proxyReq.setHeader('Content-Type', 'application/json')
proxyReq.setHeader('Content-Length', Buffer.byteLength(requestBody))
proxyReq.write(requestBody)
}
}
}
当请求到达另一个微服务时,request.body 为空,然后由 multer 写入,将 multipart/form-data参数进入request.body.
我真的需要一个解决方案,让我可以将一个字段附加到代理 restream 函数中的 multipart/form-data 请求中。
我尝试了一切来成功,但我被困住了。我希望我这边一切都清楚。如果需要,请不要害怕询问更多详细信息。我请求你的帮助。
我终于想通了如何成功。
我的代码现在看起来像这样:
const router = express()
const routes = require('~/routes')
const passport = require('passport')
const proxy = require('http-proxy-middleware')
router.use(passport.initialize())
require('./modules/passport-jwt')(passport)
router.use('/', routes)
router.use(
'/account',
passport.authenticate('jwt', { session: false }),
proxy({
target: process.env.ACCOUNT_SERVICE,
pathRewrite: { '/account': '/' },
onProxyReq: restream
})
)
const restream = async function (proxyReq, req, res, options) {
if (req.user) {
if (
req.headers['content-type'] &&
req.headers['content-type'].match(/^multipart\/form-data/)
) {
// build a string in multipart/form-data format with the data you need
const formdataUser =
`--${request.headers['content-type'].replace(/^.*boundary=(.*)$/, '')}\r\n` +
`Content-Disposition: form-data; name="reqUser"\r\n` +
`\r\n` +
`${JSON.stringify(request.user)}\r\n`
// set the new content length
proxyReq.setHeader(
'Content-Length',
parseInt(request.headers['content-length']) + Buffer.byteLength(formdataUser)
)
proxyReq.write(formdataUser)
} else {
const body = JSON.stringify({ ...req.body, reqUser: req.user })
proxyReq.setHeader('Content-Type', 'application/json')
proxyReq.setHeader('Content-Length', Buffer.byteLength(body))
proxyReq.write(body)
}
}
}
正如我在代码注释中所写:
构建 multipart/form-data 格式的字符串,必须如下所示:
------WebKitFormBoundaryiBtoTWFkpAG6CgXO\r\n
Content-Disposition: form-data; name="firstname"\r\n
\r\n\
Andrea\r\n
(在我的代码中,我将数据字符串化,因为它是一个对象);
通过将上述字符串的字节长度添加到
原始请求长度;
使用proxyReq.write函数发送新数据。
我有一个微服务,它代理每个请求并向其添加一个字段。对于普通请求,这非常简单,只需在 request.body 中添加字段并正确设置 headers 但对于 multipart/form-data 请求我有麻烦了几天以来,因为如果我在 request.body 中添加一个字段,它就会消失。
const router = express()
const routes = require('~/routes')
const passport = require('passport')
const proxy = require('http-proxy-middleware')
router.use(passport.initialize())
require('./modules/passport-jwt')(passport)
router.use('/', routes)
router.use(
'/account',
passport.authenticate('jwt', { session: false }),
proxy({
target: process.env.ACCOUNT_SERVICE,
pathRewrite: { '/account': '/' },
onProxyReq: restream
})
)
const restream = async function (proxyReq, req, res, options) {
if (req.user) {
if (
req.headers['content-type'] &&
req.headers['content-type'].match(/^multipart\/form-data/)
) {
req.body.reqUser = req.user
} else {
const requestBody = JSON.stringify({ ...req.body, reqUser: req.user })
proxyReq.setHeader('Content-Type', 'application/json')
proxyReq.setHeader('Content-Length', Buffer.byteLength(requestBody))
proxyReq.write(requestBody)
}
}
}
当请求到达另一个微服务时,request.body 为空,然后由 multer 写入,将 multipart/form-data参数进入request.body.
我真的需要一个解决方案,让我可以将一个字段附加到代理 restream 函数中的 multipart/form-data 请求中。
我尝试了一切来成功,但我被困住了。我希望我这边一切都清楚。如果需要,请不要害怕询问更多详细信息。我请求你的帮助。
我终于想通了如何成功。 我的代码现在看起来像这样:
const router = express()
const routes = require('~/routes')
const passport = require('passport')
const proxy = require('http-proxy-middleware')
router.use(passport.initialize())
require('./modules/passport-jwt')(passport)
router.use('/', routes)
router.use(
'/account',
passport.authenticate('jwt', { session: false }),
proxy({
target: process.env.ACCOUNT_SERVICE,
pathRewrite: { '/account': '/' },
onProxyReq: restream
})
)
const restream = async function (proxyReq, req, res, options) {
if (req.user) {
if (
req.headers['content-type'] &&
req.headers['content-type'].match(/^multipart\/form-data/)
) {
// build a string in multipart/form-data format with the data you need
const formdataUser =
`--${request.headers['content-type'].replace(/^.*boundary=(.*)$/, '')}\r\n` +
`Content-Disposition: form-data; name="reqUser"\r\n` +
`\r\n` +
`${JSON.stringify(request.user)}\r\n`
// set the new content length
proxyReq.setHeader(
'Content-Length',
parseInt(request.headers['content-length']) + Buffer.byteLength(formdataUser)
)
proxyReq.write(formdataUser)
} else {
const body = JSON.stringify({ ...req.body, reqUser: req.user })
proxyReq.setHeader('Content-Type', 'application/json')
proxyReq.setHeader('Content-Length', Buffer.byteLength(body))
proxyReq.write(body)
}
}
}
正如我在代码注释中所写:
构建 multipart/form-data 格式的字符串,必须如下所示:
------WebKitFormBoundaryiBtoTWFkpAG6CgXO\r\n Content-Disposition: form-data; name="firstname"\r\n \r\n\ Andrea\r\n
(在我的代码中,我将数据字符串化,因为它是一个对象);
通过将上述字符串的字节长度添加到 原始请求长度;
使用proxyReq.write函数发送新数据。