Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
169 views
in Technique[技术] by (71.8m points)

javascript - Chrome extension that runs code when ajax requests happen

So, to give a basic description of my issue.

I have a extension that is working right now (finally) that wraps phonenumbers in an type of tag.

It is working right now, but I am having an issue with anything that is dynamically loaded via JS based on user action, or based on ajax requests

For example, if I click a hotmail email, and open it, the script works, but only when I refresh the page so that the email loads and calls my contentscript.

I thought about getting around this by making the user click the icon for the extension, but that is not really the functionality that was requested.

If there is a way in Chrome to listen to ajax requests (which there seems to be) http://code.google.com/chrome/extensions/webRequest.html That is what I want to do, but I am not sure how to implement this. Do I treat it as a listener?

I figured out another way to do this based on when the DOM changes, but that made loads take a long time, there is just too much going on in the DOM to do it that way. I need to listen for AJAX requests and run my code again when they finish.

Anyhelp or even a pointer in the right direction would be great =)

Please be nice if this is a dumb question, I promise I have been Google'ing and searching forms for an answer and I can't seem to find anything. It is possible that I don't know enough to even ask the right question. I have been using javascript for about two weeks now... so my learning curve has been rough climb.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you say...

I figured out another way to do this based on when the DOM changes, but that made loads take a long time, there is just too much going on in the DOM to do it that way. I need to listen for AJAX requests and run my code again when they finish.

...where you using Mutation Events or Mutation Observers? Because I thought Observers where ment to fix that. Ive never done anything with Observers before and used Mutation Summary. It seemed able to do what you want except it didnt start observing until the document was ready/idle (not sure which) so you might have to do a scan on document ready and then fire the observer.
Here's what my test code looked like (in a content script)...

handleChanges = function(summaries) {
    // There may be more things to ignore
    var ignore = {
        SCRIPT: true,
        NOSCRIPT: true, 
        CDATA: true,
        '#comment': true
    }
    summaries.forEach(function(summary) {
        summary.added.forEach(function(node) {
            if (!ignore[node.nodeName] || (node.parentNode && !ignore[node.parentNode.nodeName]) && node.nodeValue.trim()) {
                node.nodeValue='PAEz woz ere - '+node.nodeValue;
            }
        })
    })

}

var observer = new MutationSummary({
    callback: handleChanges,
    // required
    rootNode: document,
    // optional, defaults to window.document
    observeOwnChanges: false,
    // optional, defaults to false
    queries: [{
        characterData: true
    }]
});

And another way of checking for a XMLHttpRequest is to hijack it, simply it can look like (in a content script at document start).....

function injectScript(source) {

    var elem = document.createElement("script"); //Create a new script element
    elem.type = "text/javascript"; //It's javascript
    elem.innerHTML = source; //Assign the source
    document.documentElement.appendChild(elem); //Inject it into the DOM
}

injectScript("("+(function() {

    function bindResponse(request, response) {
        request.__defineGetter__("responseText", function() {
            console.warn('Something tried to get the responseText');
            console.debug(response);
            return response;
        })
    }

    function processResponse(request,caller,method,path) {
        bindResponse(request, request.responseText);
    }

    var proxied = window.XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function(method, path, async) {
            var caller = arguments.callee.caller;
            this.addEventListener('readystatechange', function() {
                if (this.readyState === 4)
                    processResponse(this,caller,method,path);
            }, true);
        return proxied.apply(this, [].slice.call(arguments));
    };
}).toString()+")()");

...which I learn't at the mega awesome Supper Happy Fun Blog.
But as you probably know now, thats not enough for ajax driven sites. Normally you have to write something specific for the site or maybe the Mutation Observer will meet your needs.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...