是否可以捕获并记录我自己的Websocket(wss)流量

时间:2016-02-17 10:01:36

标签: javascript websocket phantomjs

如何使用PhantomJs捕获和记录来自websocket并发往我浏览器的数据流量?

1 个答案:

答案 0 :(得分:3)

您可以使用以下PhantomJS 2.1.1的工作示例尝试一种方法。 它打开http://www.websocket.org/echo.html的示例页面并打印数据流量(输入和输出)以及一些额外的调试信息。交通本身不是很有趣,但适合演示目的。 希望,这有帮助。

var webPage = require('webpage');
var page = webPage.create();

page.onConsoleMessage = function(msg) {
    console.log('\n' + msg);
};

page.onError = function() {};

page.onInitialized = function() {
    page.evaluate(function proxyWebSocket() {

        var WS = window.WebSocket;

        var WebSocket = function(url, protocols) {
            var self = this;
            console.log('Creating websocket: ' + url);

            var ws = new WS(url, protocols);

            self.addEventListener = function(type, listener, useCapture, wantsUntrusted) {
                console.log('addEventListener: ' + type + '; ' + listener + '; ' + useCapture + '; ' + wantsUntrusted);

                var newListener = function(event) {
                    console.log('dispatching event: ', JSON.stringify(event));
                    return listener(event);
                };
                return ws.addEventListener.call(ws, type, newListener, useCapture, wantsUntrusted);
            };

            self.dispatchEvent = ws.dispatchEvent.bind(ws);
            self.removeEventListener = ws.removeEventListener.bind(ws);

            self.send = function(data) {
                console.log('websocket send: ' + data);
                return ws.send(data);
            };

            self.close = function(code, reason) {
                self.trace && console.log('websocket close: ' + code + ' ' + reason);
                return ws.close(code, reason);
            };

            // https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Attributes
            var properties = [
                { name: "binaryType" },
                { name: "bufferedAmount", readOnly: true },
                { name: "extensions" },
                { name: "onclose", traceData: true },
                { name: "onmessage", traceData: true },
                { name: "onopen", traceData: true },
                { name: "onerror", traceData: true },
                { name: "protocol" },
                { name: "readyState", readOnly: true },
                { name: "url", readOnly: true }
            ];
            properties.forEach(defineProperty, self);

            function defineProperty(prop) {
                var descriptor = {
                    get: function() {
                        var result = ws[prop.name];
                        console.log('websocket get ' + prop.name + ': ' + result);
                        return result;
                    }
                };

                if (!prop.readOnly) {
                    descriptor.set = function(value) {
                        console.log('websocket set ' + prop.name + ': ' + value);
                        if (prop.traceData) {
                            var traceFn = function(event) {
                                console.log('websocket ' + prop.name + (event.data ? ': ' + JSON.stringify(event.data) : ''));
                                return value(event);
                            };
                            ws[prop.name] = traceFn;
                        } else {
                            ws[prop.name] = value;
                        }
                        return value;
                    };
                }

                Object.defineProperty(self, prop.name, descriptor);
            }
        };

        WebSocket.CONNECTING = WS.CONNECTING;
        WebSocket.OPEN = WS.OPEN;
        WebSocket.CLOSING = WS.CLOSING;
        WebSocket.CLOSED = WS.CLOSED;

        window.WebSocket = WebSocket;
    });
};

page.open("http://www.websocket.org/echo.html", function testWebSocket(status) {
    if (status === "success") {
        console.log('open status: ' + status);

        window.setTimeout(function() {
            phantom.exit();
        }, 5000);
    }
});