试图在firefox中跟踪未完成的AJAX请求的数量

Tom*_*mmy 6 javascript firefox greasemonkey sandbox xmlhttprequest

我正在使用Selenium来测试Web应用程序,不允许修改应用程序的javascript代码.我试图通过使用GreaseMonkey来覆盖XMLHttpRequest.send来跟踪未完成的AJAX请求的数量.新的send()将基本上包装设置为onreadystatechange回调的内容,检查readyState,根据需要递增或递减计数器,并调用原始回调函数.

我遇到的问题似乎是一个特权问题,因为如果我只是浏览到普通firefox浏览器中的页面,打开firebug并粘贴以下代码,它似乎工作正常:

document.ajax_outstanding = 0;
if (typeof XMLHttpRequest.prototype.oldsend != 'function') {
    XMLHttpRequest.prototype.oldsend = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = function() {
        console.log('in new send');
        console.log('this.onreadystatechange = ' + this.onreadystatechange);
        this.oldonreadystatechange = this.onreadystatechange;
        this.onreadystatechange = function() {
            if (this.readyState == 2) {
                /* LOADED */
                document.ajax_outstanding++;
                console.log('set ajax_outstanding to ' + document.ajax_outstanding);
            }
            this.oldonreadystatechange.handleEvent.apply(this, arguments);
            if (this.readyState == 4) {
                /* COMPLETED */
                document.ajax_outstanding--;
                console.log('set ajax_outstanding to ' + document.ajax_outstanding);
            }
        };
        this.oldsend.apply(this, arguments);
    };
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我在GreaseMonkey用户脚本中使用该片段的略微修改版本,如下所示:

unsafeWindow.document.ajax_outstanding = 0;
if (typeof unsafeWindow.XMLHttpRequest.prototype.oldsend != 'function') {
    unsafeWindow.XMLHttpRequest.prototype.oldsend = unsafeWindow.XMLHttpRequest.prototype.send;
    unsafeWindow.XMLHttpRequest.prototype.send = function() {
        GM_log('in new send');
        GM_log('this.onreadystatechange = ' + this.onreadystatechange);
        this.oldonreadystatechange = this.onreadystatechange;
        this.onreadystatechange = function() {
            if (this.readyState == 2) {
                /* LOADED */
                unsafeWindow.document.ajax_outstanding++;
                GM_log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding);
            }
            this.oldonreadystatechange.handleEvent.apply(this, arguments);
            if (this.readyState == 4) {
                /* COMPLETED */
                unsafeWindow.document.ajax_outstanding--;
                GM_log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding);
            }
        };
        this.oldsend.apply(this, arguments);
    };
}
Run Code Online (Sandbox Code Playgroud)

然后我转到一个页面,做一些导致AJAX请求的事情,我在javascript错误控制台中收到以下消息:

http://www.blah.com/gmscripts/overrides: in new send
uncaught exception: [Exception... "Illegal value" nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)" location: "JS frame :: file:///tmp/customProfileDir41e7266f56734c97a2ca02b1f7f528e1/extensions/%7Be4a8a97b-f2ed-450b-b12d-ee082ba24781%7D/components/greasemonkey.js :: anonymous :: line 372" data: no]
Run Code Online (Sandbox Code Playgroud)

因此,在尝试访问this.onreadystatechange时似乎抛出了异常

据推测,这是由于沙盒环境造成的.任何帮助将不胜感激.我不依赖于这个解决方案,因此欢迎任何其他建议我做我需要的.只是我尝试了其他几个,这似乎是最有希望的.要求是我需要确保在readyState变为4并且onreadystatechange回调完成执行计数器变为0 .

Tom*_*mmy 1

我最终使用了以下内容:

unsafeWindow.document.ajax_outstanding = 0;
if (typeof unsafeWindow.XMLHttpRequest.prototype.oldsend != 'function') {
    unsafeWindow.XMLHttpRequest.prototype.oldsend = unsafeWindow.XMLHttpRequest.prototype.send;
    unsafeWindow.XMLHttpRequest.prototype.send = function() {
        unsafeWindow.XMLHttpRequest.prototype.oldsend.apply(this, arguments);
        this.addEventListener('readystatechange', function() {
            if (this.readyState == 2) {
                /* LOADED */
                unsafeWindow.document.ajax_outstanding++;
                console.log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding);
            } else if (this.readyState == 4) {
                /* COMPLETED */
                unsafeWindow.document.ajax_outstanding--;
                console.log('set ajax_outstanding to ' + unsafeWindow.document.ajax_outstanding);
            }
        }, false);
    };
}
Run Code Online (Sandbox Code Playgroud)