node-http-proxy icon indicating copy to clipboard operation
node-http-proxy copied to clipboard

how to rewrite html body

Open dabeike opened this issue 10 years ago • 6 comments
trafficstars

how to change the contents of html,when the page is received from proxy? my aim is to add some html code to the page,when the page returns to client the code is like followings:

proxy.on('proxyRes', function (proxyRes, request, response){
     proxyRes.on('end',function(){
            if(proxyRes.headers['content-type']=='text/html;charset=utf-8'){
                proxyRes.write('hhhhhhhhhhh');   //this sentence may be wrong
            }
        })
})

dabeike avatar Mar 25 '15 14:03 dabeike

+1

betlab avatar Mar 26 '15 08:03 betlab

I'm not at all sure what's the best way to do this, but this is a scrip we've used successfully to inject a script into a page.

var scriptElm = '<script src="test.js"></script>';

function modifyHtml( str ) {
    // Add or script to the page
    if( str.indexOf( '</body>' ) > -1 ) {
        str = str.replace( '</body>', scriptElm + '</body>' );
    } else if ( str.indexOf( '</html>' ) > -1 ){
        str = str.replace( '</html>', scriptElm + '</html>' );
    } else {
        str = str + scriptElm;
    }

    return str;
}

proxy.on( 'proxyRes', function ( proxyRes, request, response ) {
    if( proxyRes.headers &&
        proxyRes.headers[ 'content-type' ] &&
        proxyRes.headers[ 'content-type' ].match( 'text/html' ) ) {

        var _end = response.end,
            chunks,
            _writeHead = response.writeHead;

        response.writeHead = function(){
            if( proxyRes.headers && proxyRes.headers[ 'content-length' ] ){
                response.setHeader(
                    'content-length',
                    parseInt( proxyRes.headers[ 'content-length' ], 10 ) + scriptElm.length
                );
            }

            // This disables chunked encoding
            response.setHeader( 'transfer-encoding', '' );

            // Disable cache for all http as well
            response.setHeader( 'cache-control', 'no-cache' );

            _writeHead.apply( this, arguments );
        };

        response.write = function( data ) {
            if( chunks ) {
                chunks += data;
            } else {
                chunks = data;
            }
        };

        response.end = function() {
            if( chunks && chunks.toString ) {
                _end.apply( response, [ modifyHtml( chunks.toString() ) ] );
            } else {
                _end.apply( response, arguments );
            }
        };
    }
});

kokarn avatar Mar 26 '15 08:03 kokarn

This solution must be modified to avoid the use of end( ... modify ) which uses implicilty the write() method which has been rerouted into collecting the chunks. So you finish having another chunk which is your own.

Fix:

        var _write = response.write;

...

        response.end = function() {
            if( chunks && chunks.toString )
                _write.apply( this, [ modifyHtml( chunks.toString() ) ] );
            _end.apply( this, arguments );
       };

xtof78 avatar Jun 30 '15 14:06 xtof78

Question, I would like to do the same but for request. That's, before proxyng, I need to put an extra parameter to the body and after proxy the request. How can I do it?

macscripter avatar Nov 22 '15 10:11 macscripter

Maybe this method is right for you

proxy.on('proxyRes', function (proxyRes, req, res) {
    var body = new Buffer('test body');
    proxyRes.pipe = function (res) {
      res.write(body)
      res.end()
    }
})

xingshijie avatar Jun 29 '18 10:06 xingshijie

This works for me. https://github.com/saskodh/http-proxy-response-rewrite

xianshenglu avatar Feb 08 '23 05:02 xianshenglu