захватывать страницы запросов xmlhttp с помощью usercript - PullRequest
7 голосов
/ 24 ноября 2011

У меня есть пользовательский скрипт (для chrome и FF), который добавляет значительную функциональность к странице, но недавно был сломан, потому что разработчики добавили на страницу немного AJAX. Я хотел бы изменить скрипт для прослушивания запросов страниц xmlhttp, чтобы я мог динамически обновлять добавленное содержимое на основе формата JSON responseText, который получает страница.

Поиск обнаружил множество функций, которые ДОЛЖНЫ работать и работают при запуске в консоли. Однако они ничего не делают из контекста пользовательского скрипта.

(function(open) {

    XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {

        this.addEventListener("readystatechange", function() {
            console.log(this.readyState);
        }, false);

        open.call(this, method, url, async, user, pass);
    };

})(XMLHttpRequest.prototype.open);

От: Как мне перехватить запросы XMLHttp из скрипта Greasemonkey?

Это прекрасно работает в консоли, я могу изменить this.readyState на this.responseText, и это прекрасно работает (хотя в скрипте мне понадобится это, чтобы превратить данные JSON в объект, а затем позвольте мне манипулировать ими внутри usercript. Не просто пиши в консоль). Однако, если я вставлю его в скрипт пользователя, ничего не произойдет. Похоже, что запросы xmlhttp на странице не обнаруживаются обработчиком событий в пользовательском сценарии.

Страница, выполняющая запрос, использует функцию jquery $ .get (), если это может иметь какое-либо отношение к ней. Хотя я не думаю, что это так.

Я не могу себе представить, что нет способа, похоже, что любой пользовательский скрипт, работающий на странице AJAX, хотел бы эту возможность.

1 Ответ

10 голосов
/ 24 ноября 2011

Поскольку на странице используется $.get(), перехватывать запросы еще проще.Используйте ajaxSuccess().

Это будет работать в сценарии Greasemonkey (Firefox):
Фрагмент 1:

unsafeWindow.$('body').ajaxSuccess (
    function (event, requestData)
    {
        console.log (requestData.responseText);
    }
);

Предполагаетсястраница использует jQuery обычным образом (определяется $ и т.* Фрагмент 2:

function interceptAjax () {
    $('body').ajaxSuccess (
        function (event, requestData)
        {
            console.log (requestData.responseText);
        }
    );
}

function addJS_Node (text, s_URL, funcToRun) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ    = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}

addJS_Node (null, null, interceptAjax);



Re:

"Но как мне тогда передать эти данные вскрипт? ... (так что я могу) использовать данные позже в скрипте. "

Это работает в Greasemonkey (Firefox);он также может работать в Chrome Tampermonkey :
Snippet 3:

function myAjaxHandler (requestData) {
    console.log ('myAjaxHandler: ', requestData.responseText);
}

unsafeWindow.$('body').ajaxSuccess (
    function (event, requestData) {
        myAjaxHandler (requestData);
    }
);


Но, , если не тогда вы не сможете (легко) обмениваться информацией JS между пользовательским сценарием Chrome и целевой страницей - по своему замыслу.

Обычно вы вводите весь пользовательский сценарий так, чтобы все выполнялось в области страницы.Вот так:
Фрагмент 4:

function scriptWrapper () {

    //--- Intercept Ajax
    $('body').ajaxSuccess (
        function (event, requestData) {
            doStuffWithAjax (requestData);
        }
    );

    function doStuffWithAjax (requestData) {
        console.log ('doStuffWithAjax: ', requestData.responseText);
    }

    //--- DO YOUR OTHER STUFF HERE.
    console.log ('Doing stuff outside Ajax.');
}

function addJS_Node (text, s_URL, funcToRun) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ    = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}

addJS_Node (null, null, scriptWrapper);
...