Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 试图跟踪firefox中未完成的AJAX请求的数量_Javascript_Firefox_Xmlhttprequest_Greasemonkey_Sandbox - Fatal编程技术网

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

Javascript 试图跟踪firefox中未完成的AJAX请求的数量,javascript,firefox,xmlhttprequest,greasemonkey,sandbox,Javascript,Firefox,Xmlhttprequest,Greasemonkey,Sandbox,我使用Selenium测试web应用程序,不允许修改应用程序的javascript代码。我试图通过使用GreaseMonkey覆盖XMLHttpRequest.send来跟踪未完成的AJAX请求的数量。新的send()将基本上包装设置为onreadystatechange回调的内容,检查readyState,根据需要递增或递减计数器,并调用原始回调函数 我遇到的问题似乎是一个权限问题,因为如果我只是在普通firefox浏览器中浏览到一个页面,打开firebug并粘贴以下代码,它似乎工作正常: d

我使用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);
    };
}
现在,如果我在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);
    };
}
我进入一个页面,做一些导致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]
因此,在尝试访问此.onreadystatechange时,它似乎引发了异常

这大概是由于沙盒环境造成的。
任何帮助都将不胜感激。我不喜欢这个解决方案,所以欢迎任何其他关于我需要做什么的建议。只是我试过其他几种,这似乎是最有希望的。要求是我需要确保在readyState变为4并且onreadystatechange回调完成执行后计数器变为0。

我使用了以下方法:

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);
    };
}

我自己做了一些事情:(2015年1月22日更新)

脚本(应先运行,然后再运行):

以及JSFIDLE的测试脚本:

window.onload = function() {
    var btn = document.querySelector('button'),
        active = btn.querySelector('span');

    btn.onclick = function() {
        // jQuery for easy ajax. `delay` is a jsFiddle argument
        // to keep some requests active longer.
        jQuery.post('/echo/json/', {
            delay: Math.random() * 3,
        });
    };

    updateActive();

    function updateActive() {
        active.textContent = XMLHttpRequest.active;
        requestAnimationFrame(updateActive);
    }
};

它会在每个动画帧(每秒约60次)更新按钮中的计数器,与AJAX请求分开。无论您做什么,无论您点击它的速度和次数有多快,计数器在几秒钟后应始终显示为0。

您真的给出了本地主机地址还是我的眼睛?=)请注意,对
XMLHttpRequest.send
的修改需要在发送任何AJAX请求之前安装,否则计数器可能会出错。此外,我认为最好是在调用<代码>之后,减去<代码>活动< /代码>。
window.onload = function() {
    var btn = document.querySelector('button'),
        active = btn.querySelector('span');

    btn.onclick = function() {
        // jQuery for easy ajax. `delay` is a jsFiddle argument
        // to keep some requests active longer.
        jQuery.post('/echo/json/', {
            delay: Math.random() * 3,
        });
    };

    updateActive();

    function updateActive() {
        active.textContent = XMLHttpRequest.active;
        requestAnimationFrame(updateActive);
    }
};