在转发到代理目标并将响应发送回客户端之前,编辑POST参数

Edit POST parameters prior to forwarding to a proxy target and sending response back to client

本文关键字:客户端 参数 POST 编辑 代理 转发 目标 响应      更新时间:2023-12-18

我有一个node/express代理设置,使用http代理中间件将请求路由到java tomcat web服务(代理目标)。

在将请求转发到代理目标之前,我需要将POST表单数据注入到上下文类型为"application/x-www-form-urlencoded"的请求rawbody中。在向客户端发送响应之前,代理响应将需要删除相同的post参数。

我使用了许多不同的代理,包括http代理、http代理中间件、节点代理和express代理,但这些模块似乎都没有允许POST参数操作的解决方案

这个问题最初发布在https://github.com/chimurai/http-proxy-middleware/issues/61#issuecomment-205494577

'use strict';
var express = require('express');
var router = express.Router();
//var request = require("request");
var proxy_filter = function (path, req) {
    return path.match('^/report') && ( req.method === 'GET' ||    req.method === 'POST' );
};
var proxy_options = {
    target: 'http://localhost:8080',
    logLevel: 'debug',
    //logProvider:
    onError(err, req, res) {
        res.writeHead(500, {
            'Content-Type': 'text/plain'
        });
        res.end('Something went wrong. And we are reporting a custom error message.' + err);
    },
    onProxyRes(proxyRes, req, res) {
        //proxyRes.headers['x-added'] = 'foobar';     // add new header to response
        //delete proxyRes.headers['x-removed'];       // remove header from response
    },
    onProxyReq(proxyReq, req, res) {
        if ( req.method == "POST" && req.body ) {
            proxyReq.write( encodeURIComponent( JSON.stringify(   req.body ) ) );
            proxyReq.end();
        }
    }
};
// Proxy configuration
var proxy = require( 'http-proxy-middleware' )( proxy_filter, proxy_options );
/* GET home page. */
router.get('/', function(req, res, next) {
    res.render('index', { title: 'Node.js Express Proxy Test' });
});
router.all('/report/*', function( req, res, next ) {
    //req.body.jdbc_sas = 'jdbc:postgresql://pg_dev:5432/sasdb';
    //req.body.jdbc_agency = 'jdbc:postgresql://pg_dev:5432/agency0329';
    //console.log('proxy body:',req.body);
    proxy( req, res, next );
} );
module.exports = router;

如有任何建议,我们将不胜感激。

尊敬的

沃伦。

好的,这是最终解决方案。

以下示例允许您在转发到代理目标之前注入POST参数。据我所知,您不需要从代理目标响应中清除任何参数,因为它维护了原始POST请求的副本。

顺便说一句,这也允许http代理中间件与主体解析器一起工作。

示例节点快速路由文件:

'use strict';
var express = require('express');
var router = express.Router();
var proxy_filter = function (path, req) {
    return path.match('^/docs') && ( req.method === 'GET' || req.method === 'POST' );
};
var proxy_options = {
    target: 'http://localhost:8080',
    pathRewrite: {
        '^/docs' : '/java/rep/server1' // Host path & target path conversion
    },
    onError(err, req, res) {
        res.writeHead(500, {
            'Content-Type': 'text/plain'
        });
        res.end('Something went wrong. And we are reporting a custom error message.' + err);
    },
    onProxyReq(proxyReq, req, res) {
        if ( req.method == "POST" && req.body ) {
            // Add req.body logic here if needed....
           // ....
            // Remove body-parser body object from the request
            if ( req.body ) delete req.body;
            // Make any needed POST parameter changes
            let body = new Object();
            body.filename = 'reports/statistics/summary_2016.pdf';
            body.routeid = 's003b012d002';
            body.authid = 'bac02c1d-258a-4177-9da6-862580154960';
            // URI encode JSON object
            body = Object.keys( body ).map(function( key ) {
                return encodeURIComponent( key ) + '=' + encodeURIComponent( body[ key ])
            }).join('&');
            // Update header
            proxyReq.setHeader( 'content-type', 'application/x-www-form-urlencoded' );
            proxyReq.setHeader( 'content-length', body.length );
            // Write out body changes to the proxyReq stream
            proxyReq.write( body );
            proxyReq.end();
        }
    }
};
// Proxy configuration
var proxy = require( 'http-proxy-middleware' )( proxy_filter, proxy_options );
/* GET home page. */
router.get('/', function(req, res, next) {
    res.render('index', { title: 'Node.js Express Proxy Test' });
});
router.all('/document', proxy );
module.exports = router;