monitoring history.pushstate from a chrome extensi

2019-01-14 22:10发布

问题:

I am developing a Chrome extension to tweak Facebook. However, catching browsing actions within HTML5-enabled sites such as Facebook requires an override of window.history.pushState as explained in this SO question.

Unfortunately, it seems that Chrome's isolated worlds prevent this sort of override. Is there any other method of catching history changes (other than polling document.location.href)?

回答1:

Yes,

One way is to create a script tag and put your code there:

html = "window.history.pushState = function(a,b,c) { alert('Change !'); };";

var headID = document.getElementsByTagName("head")[0];         
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.innerHTML = html;
headID.appendChild(newScript);


回答2:

Not sure whether you trying to do this in background.js or content.js, but if it is the former, you can do so using webNavigation events:

You need to set permissions for webNavigation in manifest.json:

  "permissions": [
     "webNavigation"
  ],

Then in background.js:

  chrome.webNavigation.onHistoryStateUpdated.addListener(function(details) {
        console.log('Page uses History API and we heard a pushSate/replaceState.');
        // do your thing
  });

Source: Chrome Extension docs for webNavigation



回答3:

Building on @Boris's answer: to continue with the default action, save a reference to the original pushState function, and then call it:

var headID = document.getElementsByTagName("head")[0];         
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = chrome.extension.getURL('script.js');
headID.appendChild(newScript);

script.js:

window.history.pushState = (function(nativePushState) {
    return function(a,b,c) {
        // Do something
        nativePushState.apply(this, arguments); //Continue by calling native history.pushState
    };
})(window.history.pushState)