3

I'm creating a custom Chrome extension, which is going to retrieve data about an active tab before sending it to a secondary website.

I've been trying to find a method on how to retrieve the console output for an active tab. chrome.tabs.getSelected seemed promising at first, however, it doesn't offer an output of the console text. I've been digging for couple of hours without much success of finding a method that could give me this info.

Could anyone point me in the right direction please?

Edit:

As a way to keep track of everything I've tried so far, for myself and others, I will add info below.

I've found a possible solution which may work for me. The below code will extend the console methods log, error and warn. I'm currently researching for a method that maybe able to attach this code to the active tab, so I can collect the console outputs in the arrays and then make these available on my extension to be sent over to the secondary website.

I will post more info as I progress through it.

var logs = [],
    cLogs = [],
    cErrors = [],
    cWarns = [],
    _log = console.log,
    _error = console.error,
    _warn = console.warn;

console.log = function () {
    for (var i = 0; i < arguments.length; i++) {
        logs.push(arguments[i]);
        cLogs.push(arguments[i]);
    }

    _log.apply(this, arguments);
};

console.error = function () {
    for (var i = 0; i < arguments.length; i++) {
        logs.push(arguments[i]);
        cErrors.push(arguments[i]);
    }

    _error.apply(this, arguments);
};

console.warn = function () {
    for (var i = 0; i < arguments.length; i++) {
        logs.push(arguments[i]);
        cWarns.push(arguments[i]);
    }

    _warn.apply(this, arguments);
};

console.log('welcome');
console.error({'foobar': ['foo','bar']});
console.warn({'foo':'bar'});

_log(logs);
adamj
  • 4,672
  • 5
  • 49
  • 60
  • Overwrite the console functions. – Daniel Herr Apr 26 '17 at 03:05
  • @DanielHerr Thanks Daniel! Came across that shortly after posting and it seems to be the right way to go. I'll have to find a way to attach it to the active tab, so there's still a wee bit to go. – adamj Apr 26 '17 at 03:27
  • If you get it working, may I recommend that you post the solution as an answer, rather than as an edit? That way, people can see that the question has an answer. They may even upvote you. – Dawood ibn Kareem Apr 26 '17 at 03:29
  • @DawoodibnKareem I always do ;) – adamj Apr 26 '17 at 03:32

1 Answers1

3

This issue is significantly harder than it appears.

APIs like chrome.tabs have no access to a tab's console. In fact, no "standard" API does.

One could expect a content script running in the context of the page to be able to access it. However, there's no way to access previous output of the console from a JavaScript context.

The method you quote in your update (creating wrappers around console.* functions) can only capture future invocations of those functions, and won't capture things like errors from the JS runtime itself (e.g. unhandled exceptions or network errors). As such, to access console from an arbitrary tab, you'll need to inject this code into every tab, before it loads, even if you only rarely use it.

It is further complicated by the fact that content scripts do not, in fact, run in the same context. To override console for the page itself, you'll need to inject the script in the page context.

So, to summarize:

  1. You can do it by overriding console.* functions and listening to error event on window object, but it has to be done in page context by a document_start content script injecting code into every page. Extracting this data from the page context will be a challenge in itself.

    Downsides:

    • It hurts overall browser performance.
    • It won't see some browser-initiated messages that go directly to console.
  2. You can take the big hammer and use chrome.debugger API. This API has the same level of access to the page as the Dev Tools themselves - therefore, it's possible to obtain the full console output history.

    Downsides:

All in all, what you're trying to achieve is a hard task with fragile solutions. Perhaps you need to rethink your approach.

wOxxOm
  • 65,848
  • 11
  • 132
  • 136
Xan
  • 74,770
  • 16
  • 179
  • 206
  • Basically, as you mentioned, I've planned to inject a script which would contain the above code before anything else starts loading. Performance is not something I'm concerned about. Although, I'm still trialling things, so I'm not yet sure if this is the best method. I had look at the documentation for the `chrome.debugger` yesterday evening as well, but I don't think this one is a good fit either. I appreciate your answer and will be exploring things a bit more. However, I've seen extensions/websites extract the console history, so I know this can be done. – adamj Apr 27 '17 at 03:17