BenR
BenR

Reputation: 2936

Why does chrome.webRequest.OnBeforeRequest fire before chrome.webNavigation.onBeforeNavigate?

I'm trying to understand the logic. In my mind, onBeforeNavigate event should complete before we hear anything from any request. But I find that a onBeforeRequest event fires first. Here's sample code that will demonstrate what I mean.

test.js

function Test(url) {
  chrome.tabs.create({ url: "" }, function (tab) {
    chrome.webNavigation.onBeforeNavigate.addListener(function (details) {
      console.log("chrome.webNavigation.onBeforeNavigate hit on " + details.timeStamp);
    });

    chrome.webRequest.onBeforeRequest.addListener(function (details) {
      console.log("chrome.webRequest.onBeforeRequest hit on " + details.timeStamp);
    }, {
      tabId: tab.id,
      urls: ["<all_urls>"]
    });

    chrome.tabs.update(tab.id, {
      url: url
    });
  });
}
Test("http://www.steam.com");    // Simple url with only two requests

Resulting console messages:

chrome.webRequest.onBeforeRequest hit on 1437083141916.896
chrome.webNavigation.onBeforeNavigate hit on 1437083141916.906
chrome.webRequest.onBeforeRequest hit on 1437083141940.385

manifest.json

{
  "background": {
    "persistent": true,
    "scripts": [
      "test.js"
    ]
  },
  "manifest_version": 2,
  "name": "Test",
  "permissions": [
    "<all_urls>",
    "webNavigation",
    "webRequest"
  ],
  "version": "1.0"
}

Here is a view of the three details, in order of their event fire:

// first chrome.webRequest.onBeforeRequest
{
  "frameId" : 0,
  "method" : "GET",
  "parentFrameId" : -1,
  "requestId" : "72285",
  "tabId" : 1312,
  "timeStamp" : 1437083141916.896,
  "type" : "main_frame",
  "url" : "http://www.steam.com/"
},

// chrome.webNavigation.onBeforeNavigate
{
  "frameId" : 0,
  "parentFrameId" : -1,
  "processId" : 3567,
  "tabId" : 1312,
  "timeStamp" : 1437083141916.906,
  "url" : "http://www.steam.com/"
},

// second chrome.webRequest.onBeforeRequest
{
  "frameId" : 0,
  "method" : "GET",
  "parentFrameId" : -1,
  "requestId" : "72286",
  "tabId" : 1312,
  "timeStamp" : 1437083141940.385,
  "type" : "image",
  "url" : "http://www.steam.com/images/pipebackwhite.gif"
}

Upvotes: 2

Views: 1609

Answers (2)

Martins Balodis
Martins Balodis

Reputation: 2068

OnBeforeRequest does not always fire before onBeforeNavigate. In a case the page being loaded immediately executes a window.location="example.com" redirect, first you will get onBeforeNavigate event and only then onBeforeRequest.

Chrome API documentation states that there is no defined order:

There is no defined ordering between events of the webRequest API and the events of the webNavigation API."

Upvotes: 1

Brian
Brian

Reputation: 1553

If you think about when each event is firing this should make sense.

OnBeforeRequest is firing before you even make the request to the server:

Fires when a request is about to occur. This event is sent before any TCP
connection is made and can be used to cancel or redirect requests.

On the other side, onBeforeNavigate fires before the page navigates to the next page:

Fired when a navigation is about to occur.

If you think about how a browser works, it fires a request to the server and if it's a typical GET, the browser navigates to the new page on the request based off of the headers. However, this happens on the actual request, and OnBeforeRequest is being run before anything fires off to the server at all.

So, you make a request, the api says:

  • A request is made, before I do anything, I should fire OnBeforeRequest
  • OK, I processed this request, it's making me navigate/redirect, before I do that, I should do OnBeforeNavigate

Upvotes: 5

Related Questions