【问题标题】:Edit POST parameters prior to forwarding to a proxy target and sending response back to client在转发到代理目标并将响应发送回客户端之前编辑 POST 参数
【发布时间】:2016-04-05 02:33:55
【问题描述】:

我有一个 node/express 代理设置,使用 http-proxy-middleware 将请求路由到 java-tomcat Web 服务(代理目标)。

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

我使用了许多不同的代理,包括 http-proxy、http-proxy-middleware、node-proxy 和 express-proxy,但这些模块似乎都没有可用的解决方案来允许 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;

非常感谢任何建议。

尊敬的,

沃伦。

【问题讨论】:

    标签: javascript node.js express proxy


    【解决方案1】:

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

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

    另一方面,这也允许 http-proxy-middleware 与 body-parser 一起工作。

    示例节点快速路由文件:

    '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;
    

    【讨论】:

    • 有没有办法可以修改/添加req.custom = 'value' 并将其传递给所有请求的代理? .我也在 github 提出了一个问题github.com/chimurai/http-proxy-middleware/issues/66
    • 只需在正文中添加一个参数 - 即:body.custom = "value" 并将其发布到代理。如果你想让它适用于所有方法,你需要使用 route.all 作为路由处理程序,然后修改代理过滤器来处理你想要接受的方法/动词。
    • 基于这个github.com/tomalex0/middleware-patterns/blob/master/index.js你能建议代码添加/修改req.myvar = 'newval'
    • 正文解析器提示让我很开心!非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多