Runtime.connect before HTTP requests

learning

(Shockagent) #1

I’m wondering if the connection between content script and background is always established before any webrequest when I use “run_at”: “document_start” in manifest.json and runtime.connect is called at the beginning of content script.

for example:

Background script:

Background
// BACKGROUND script
'use strict';
class Background {
  constructor() {
    console.log("BACKGROUND: constructor");
    this.ports = [];
    this.urlFilter = {...};

    this.onConnect = this.onConnect.bind(this);
    this.onMessage = this.onMessage.bind(this);
    this.onDisconnect = this.onDisconnect.bind(this);
    this.onBeforeNavigate = this.onBeforeNavigate.bind(this);
    this.onCommitted = this.onCommitted.bind(this);
    this.onDOMContentLoaded = this.onDOMContentLoaded.bind(this);

    this.onBeforeFirstRequest = this.onBeforeFirstRequest.bind(this);
    this.onBeforeXHRRequest = this.onBeforeXHRequest.bind(this);

    browser.runtime.onConnect.addListener(this.onConnect);
    browser.webRequest.onBeforeRequest.addListener(this.onBeforeFirstRequest, {
      urls: ["..."], types: ["main_frame"]
    }, ["blocking"]);
    browser.webRequest.onBeforeRequest.addListener(this.onBeforeXHRRequest, {
      urls: ["...."]
    }, ["blocking"]);
    browser.webNavigation.onBeforeNavigate.addListener(this.onBeforeNavigate, {
      url: [{...}]
    });
    browser.webNavigation.onCommitted.addListener(this.onCommitted, this.urlFilter);
    browser.webNavigation.onDOMContentLoaded.addListener(this.onDOMContentLoaded, this.urlFilter);
  }

  onConnect(port) {
    console.group("BACKGROUND");
    console.log("port onConnect");
    this.ports[port.sender.tab.id] = port;
    this.ports[port.sender.tab.id].onMessage.addListener(this.onMessage);
    this.ports[port.sender.tab.id].onDisconnect.addListener(this.onDisconnect);
    console.log(this.ports);
    console.groupEnd();
  }

  onMessage(msg) {
    // receive messages
  }

  onDisconnect(port) {
    console.log("BACKGROUND: port onDisconnect", port);
    this.ports.splice(port.sender.tab.id, 1);
    console.log("BACKGROUND: ports", this.ports);
  }

  onBeforeFirstRequest(details) {
    console.group("BACKGROUND")
    console.log("onBeforeFirstRequest");
    console.log(details.url);
    console.log(this.ports);
    console.groupEnd();
    return;
  }

  onBeforeXHRRequest(details) {
    console.log("BACKGROUND: onBeforeXHRRequest");
  }

  onBeforeNavigate(details) {
    console.log("BACKGROUND: onBeforeNavigate");
  }

  onCommitted(details) {
    console.log("BACKGROUND: onCommitted");
  }

  onDOMContentLoaded(details) {
    console.log("BACKGROUND: onDOMContentLoaded");
  }
}

var background = new Background();

and

Content script:

Content

// CONTENT script

'use strict';

class Content {
  constructor() {
    console.log("CONTENT: constructor");
    this.port = browser.runtime.connect();
    this.onMessage = this.onMessage.bind(this);
    this.port.onMessage.addListener(this.onMessage);
    console.log("CONTENT: port connected to BKGD");

    this.onUnload = this.onUnload.bind(this);
    window.addEventListener("unload", this.onUnload);
  }

  onMessage(msg) {
    console.group("CONTENT: onMessage");
    console.log(msg);
    console.groupEnd();
  }

  onUnload(event) {
    console.log("CONTENT: onunload");
    this.port.disconnect();
  }
}

var content = new Content();

in console I find the following messages:

Console log
BACKGROUND: constructor Background.js:8:5
BACKGROUND: onBeforeNavigate Background.js:107:5
BACKGROUND Background.js:66:5
 onBeforeFirstRequest Background.js:67:5
BACKGROUND: onCommitted Background.js:111:5
CONTENT: constructor Content.js:15:5
CONTENT: port connected to BKGD Content.js:19:5
BACKGROUND Background.js:44:5
 port onConnect Background.js:45:5
BACKGROUND: onBeforeXHRRequest Background.js:75:5
BACKGROUND: onBeforeXHRRequest Background.js:75:5
BACKGROUND: onBeforeXHRRequest Background.js:75:5
CONTENT: onMessage Content.js:26:5
 Object { ... } Content.js:27:5
CONTENT: onMessage Content.js:26:5
 Object { ... } Content.js:27:5
CONTENT: onMessage Content.js:26:5
 Object { ... } Content.js:27:5
BACKGROUND: onDOMContentLoaded Background.js:115:5
CONTENT: onMessage Content.js:26:5
 Object { ... } Content.js:27:5

i see that connection between content and backround is established before any HTTP traffic… is it guaranteed that it is always like this?

or should I block HTTP requests and wait for the connection to be established?

P.S.
it’s my first post…I hope it’s all right… and sorry for my English :smile:


(Niklas Gollenstede) #2

Your post looks very well formatted, you just somehow managed to disable the syntax highlighting on the code blocks (but I don’t think they are necessary to answer the question).

AFAIK there is not even a guarantee when your content script is injected. (Couldn’t find that in the docs now, though. Maybe something changed here.)

But don’t you (in absence of cached pages) create a chicken-egg problem here? No website before HTTP, but you want no HTTP before the content script connects from a website …