NodeJS - отредактируйте и проксируйте запрос multipart / form-data - PullRequest
0 голосов
/ 18 октября 2019

У меня есть микросервис, который проксирует каждый запрос, добавляя к нему еще одно поле. С обычными запросами это очень просто, просто добавьте поле в request.body и правильно установите заголовки, но для запросов 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 .

Мне действительно нужно решение, которое позволит мне добавить поле в multipart /запрос данных формы в функции прокси restream .

Я попробовал все, чтобы преуспеть в этом, но я застрял. Я надеюсь, что все ясно с моей стороны. Не бойтесь спрашивать подробности, если они вам нужны. Я прошу вашей помощи.

1 Ответ

0 голосов
/ 24 октября 2019

Я наконец понял, как добиться успеха. Мой код теперь выглядит так:

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=(.*)$/, '$1')}\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']) + formdataUser.length
            )

            proxyReq.write(formdataUser)
        } else {
            const body = JSON.stringify({ ...req.body, reqUser: req.user })
            proxyReq.setHeader('Content-Type', 'application/json')
            proxyReq.setHeader('Content-Length', body.length)
            proxyReq.write(body)
        }
    }
}

Как я уже писал в комментариях к коду:

  1. Создайте строку в формате multipart / form-data, которая должна выглядеть следующим образом:this:

    ------WebKitFormBoundaryiBtoTWFkpAG6CgXO\r\n
    Content-Disposition: form-data; name="firstname"\r\n
    \r\n\
    Andrea\r\n
    

    (В моем коде я упорядочил данные, потому что это был объект);

  2. Установите заголовок Content-Length, добавив приведенную выше строкудлина до исходной длины запроса;

  3. Используйте функцию proxyReq.write для отправки новых данных.

...