开发者

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
    开发者_StackOverflowif (!(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.


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).


I don't think you'll be able to do this in a general way. Remember that ajax calls could be in any format (html, xml, json, etc) and then the javascript that initiated them can do whatever it wants to the data before it inserts it into the document. You can't really monitor this, unless you are doing it for a specific case where you know what to look for. Or by pure brute force, where you keep track of the contents of the page and check if anything has changed on regular intervals.


I don't think you can do this, and even if you could, there are other methods for loading aysnc content, such as JSON-P

Another option is to set up a function that monitors the body element for any new additions to the DOM. I don't think this is a native browser event, so you would have to poll using setTimeout(). Also note that iterating over all the DOM elements can be time consuming. The following page has some events that may help: http://www.quirksmode.org/dom/events/index.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜