How to capture http messages from Request Node library with Fiddler

前端 未结 5 1199
清酒与你
清酒与你 2021-02-12 12:33

Regular client initiated requests to the node server are captured fine in Fiddler. However, requests sent from node to a web service are not captured. It did not help to pass in

相关标签:
5条回答
  • 2021-02-12 12:50

    I've been wanting the same... an equivalent of the Network tab in chrome DevTools, only for Nodejs. Unfortunately, it doesn't appear as though one exists. I don't have Fiddler on macos, so this is how I went about stubbing the require('http') methods to log and pass though. Leaving this here in case I need it again or someone else finds it helpful. You can turn it on by attaching a debugger and require('filename')() the file containing this script.

    module.exports = () => {
        const http = require('http');
        http._request = http.request;
    
        global.DO_LOG_AJAX = true;
        const log = str => {
            if (global.DO_LOG_AJAX) {
                console.debug(str);
            }
        };
    
        const flushLog = (requestLines, responseLines) => {
            if (global.DO_LOG_AJAX) {
                log([
                    '----------------Begin Request-----------------------------------',
                    ...requestLines,
                    '----------------End Request / Begin Response--------------------',
                    ...responseLines,
                    '----------------End Reponse-------------------------------------',
                ].join('\n'));
            }
        };
    
        let write;
        let end;
        http.request = (...requestParams) => {
            const req = http._request(...requestParams);
            const { method, path, headers, host, port } = requestParams[0];
            const requestLogLines = [];
            requestLogLines.push(`${method} ${path}`);
            requestLogLines.push(`Host: ${host}:${port}`);
            for (const header of Object.keys(headers)) {
                requestLogLines.push(`${header}: ${headers[header]}`);
            }
            write = write || req.write;
            end = end || req.end;
    
            req.on('error', err => {
                log({ err });
            });
    
            req._write = write;
            req._end = end;
            const requestBody = [];
            req.write = (...writeParams) => {
                requestBody.push(writeParams[0].toString());
                return req._write(...writeParams);
            };
            req.end = (...endParams) => {
                if (endParams[0]) {
                    requestBody.push(endParams[0].toString());
                }
                requestLogLines.push('');
                requestLogLines.push(requestBody.join(''));
                return req._end(...endParams);
            };
    
            const responseLogLines = [];
            req.once('response', response => {
                const responseBody = [];
                responseLogLines.push(`${response.statusCode} ${response.statusMessage}`);
                for (const header of Object.keys(response.headers)) {
                    responseLogLines.push(`${header}: ${response.headers[header]}`);
                }
                const onData = chunk => {
                    responseBody.push(chunk.toString());
                };
                const onClose = err => {
                    responseLogLines.push('');
                    responseLogLines.push(responseBody.join(''));
                    responseLogLines.push('');
                    responseLogLines.push(`--- ERROR --- ${err.toString()}`);
                    flushLog(requestLogLines, responseLogLines);
                    req.removeListener('data', onData);
                };
                const onEnd = () => {
                    responseLogLines.push('');
                    responseLogLines.push(responseBody.join(''));
                    flushLog(requestLogLines, responseLogLines);
                    req.removeListener('data', onData);
                };
                response.on('data', onData);
                response.once('close', onClose);
                response.once('end', onEnd);
            });
    
            return req;
        };
    };

    0 讨论(0)
  • 2021-02-12 12:56

    I just tried to do this myself (using Fiddler and the request library from npm). Here's how I got it working:

    process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; // Ignore 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' authorization error
    
    // Issue the request
    request(
    {
        method: "GET",
        uri: "https://secure.somewebsite.com/",
        proxy: "http://127.0.0.1:8888" // Note the fully-qualified path to Fiddler proxy. No "https" is required, even for https connections to outside.
    },
    function(err, response, body) {
        console.log("done");
    });
    

    This is with Fiddler2 using the default port and proxy options (and no proxy authentication).

    0 讨论(0)
  • 2021-02-12 12:58

    To do this on an ad-hoc basis, without changing your code, you can use environment variables.

    Request respects:

    • HTTP_PROXY
    • HTTPS_PROXY
    • NO_PROXY

    So, to proxy just set these in your console before running your process.

    For example, to setup http and https proxy use:

    set HTTP_PROXY="http://127.0.0.1:8888"
    set HTTPS_PROXY="http://127.0.0.1:8888"
    set NODE_TLS_REJECT_UNAUTHORIZED=0
    

    The latter line stops issues with SSL through the fiddler proxy.

    0 讨论(0)
  • 2021-02-12 13:07

    The proxy option should be a full url, like this:

    proxy : "http://127.0.0.1:8888"
    
    0 讨论(0)
  • 2021-02-12 13:14

    Fiddler works by setting your "Internet Options" (from start menu) "Connections" > "LAN Settings" > "Proxy Server" to its port, thus making all HTTP traffic (clients which obey this setting) go through it.

    You should point your node.js client lib to use a proxy, the settings are written in that options dialog after you start Fiddler.

    0 讨论(0)
提交回复
热议问题