Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve and Modify content of an XMLHttpRequest

I am working on a browser plugin for Firefox, Safari, Chrome that will intercept data on the page, run it against a regex and then if it matches - reformat it. I have this working on page load using:

var meth = {
  replaceInElement : function(element, find, replace) {
        // iterate over child nodes and replace
  },
  run : function(evt){
    // doc is the document that triggered "run" event
    if (!(evt.target.nodeName === "#document")) { return; }
    var doc = evt.target; // document that triggered "onload" event
    if (!(doc instanceof HTMLDocument)) { return; }
    if (!doc.location) { return; }

    // perform substitutions on the loaded document
    var find = /regex/gi

    meth.replaceInElement(doc.body, find, function(match) {
        var new_content;
        //do stuff
        return new_content;
    });

    //content.document.addEventListener('DOMNodeInserted', ezcall.node_inserted, false);
  }
}

window.addEventListener("load", meth.run, false);

This is working for static pages, but for anything using ajax calls, it fails. I cannot find the right listener or figure out how to intercept the XMLHttpRequest.

I have tried similar event listeners for XMLHttpRequest with no luck.

XMLHttpRequest.addEventListener('load', meth.run, false);

I would like to either intercept the request and modify the content. Or find the target that was updated and scan it after the ajax call is finished.

UPDATE:

I will accept an answer that says it cannot be done, but I will need some supporting data as to why it cannot be done.

like image 987
Geoff Lanotte Avatar asked May 26 '11 01:05

Geoff Lanotte


1 Answers

Rather dirty but you can overwrite XMLHttpRequest.prototype.open. Here is a Demo page. Since you're writing an extension, you must put this code in page context:

(function() {
    // save reference to the native method
    var oldOpen = XMLHttpRequest.prototype.open;
    // overwrite open with our own function
    XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
        // intercept readyState changes
        this.addEventListener("readystatechange", function() {
            // your code goes here...
            console.log("Interception :) " + this.readyState);
        }, false);
        // finally call the original open method
        oldOpen.call(this, method, url, async, user, pass);
    };
})();

After this you can do anything I guess. Replace instance.readystatechange, replace instance.addEventListener, or listen to mutation events (although they are deprecated).

like image 134
25 revs, 4 users 83% Avatar answered Nov 03 '22 00:11

25 revs, 4 users 83%