Java 如何检查浏览器是否有待处理的请求(Ajax 及其变体)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24298925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:21:26  来源:igfitidea点击:

How to checkif there are pending requests (Ajax and its variants) from browser

javajqueryajaxseleniumwebdriver

提问by raju

Some of the sites I deal with have heavy ajax requests. I plan to wait for Ajax request completion before clicking for asserting for element. Currently I use

我处理的一些网站有大量的 ajax 请求。我计划在单击断言元素之前等待 Ajax 请求完成。目前我使用

try {
    if (driver instanceof JavascriptExecutor) {
        JavascriptExecutor jsDriver = (JavascriptExecutor)driver;

        for (int i = 0; i< timeoutInSeconds; i++) 
        {
            Object numberOfAjaxConnections = jsDriver.executeScript("return jQuery.active");
            // return should be a number
            if (numberOfAjaxConnections instanceof Long) {
                Long n = (Long)numberOfAjaxConnections;
                System.out.println("Number of active jquery ajax calls: " + n);
                if (n.longValue() == 0L)  break;
            }
            Thread.sleep(1000);
        }
    }
    else {
       System.out.println("Web driver: " + driver + " cannot execute javascript");
    }
}
catch (InterruptedException e) {
    System.out.println(e);
}

But it works well for Ajax requests but not for any similar requests with variants of jQuery libraries.

但它适用于 Ajax 请求,但不适用于任何带有 jQ​​uery 库变体的类似请求。

Note:

笔记:

document.readyState == 'complete'

It doesn't work for Ajax requests or any other similar alternatives.

它不适用于 Ajax 请求或任何其他类似的替代方案。

Neither tests are written by me or belong to single webapp. So I can't edit the webapp.

两个测试都不是我编写的,也不是属于单个 webapp。所以我无法编辑 webapp。

采纳答案by raju

I found the answer and it worked for few Ajax and non-ajax sites I checked. After this patch I no longer need to do implicit waits even for ajax heavy pages, LeGac pointed out the following code in one of his comments to the question.

我找到了答案,它适用于我检查过的少数 Ajax 和非 ajax 站点。在此补丁之后,即使是 ajax 重页,我也不再需要进行隐式等待,LeGac 在他对该问题的评论之一中指出了以下代码。

public static void checkPendingRequests(FirefoxDriver driver) {
    int timeoutInSeconds = 5;
    try {
        if (driver instanceof JavascriptExecutor) {
            JavascriptExecutor jsDriver = (JavascriptExecutor)driver;

            for (int i = 0; i< timeoutInSeconds; i++) 
            {
                Object numberOfAjaxConnections = jsDriver.executeScript("return window.openHTTPs");
                // return should be a number
                if (numberOfAjaxConnections instanceof Long) {
                    Long n = (Long)numberOfAjaxConnections;
                    System.out.println("Number of active calls: " + n);
                    if (n.longValue() == 0L)  break;
                } else{
                    // If it's not a number, the page might have been freshly loaded indicating the monkey
                    // patch is replaced or we haven't yet done the patch.
                    monkeyPatchXMLHttpRequest(driver);
                }
                Thread.sleep(1000);
            }
        }
        else {
           System.out.println("Web driver: " + driver + " cannot execute javascript");
        }
    }
    catch (InterruptedException e) {
        System.out.println(e);
    }    
}



public static void monkeyPatchXMLHttpRequest(FirefoxDriver driver) {
    try {
        if (driver instanceof JavascriptExecutor) {
            JavascriptExecutor jsDriver = (JavascriptExecutor)driver;
            Object numberOfAjaxConnections = jsDriver.executeScript("return window.openHTTPs");
            if (numberOfAjaxConnections instanceof Long) {
                return;
            }
            String script = "  (function() {" +
                "var oldOpen = XMLHttpRequest.prototype.open;" +
                "window.openHTTPs = 0;" +
                "XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {" +
                "window.openHTTPs++;" +
                "this.addEventListener('readystatechange', function() {" +
                "if(this.readyState == 4) {" +
                "window.openHTTPs--;" +
                "}" +
                "}, false);" +
                "oldOpen.call(this, method, url, async, user, pass);" +
                "}" +
                "})();";
            jsDriver.executeScript(script);
        }
        else {
           System.out.println("Web driver: " + driver + " cannot execute javascript");
        }
    }
    catch (Exception e) {
        System.out.println(e);
    }
}

After every step you would need to call

在每一步之后,你都需要打电话

checkPendingRequests(driver);

回答by Purus

Based on our discussion over the comments, this might work for you.

根据我们对评论的讨论,这可能对您有用。

With prototype.js:

使用prototype.js:

var ACTIVE_REQUESTS = 0; // GLOBAL

ACTIVE_REQUESTS++
new Ajax.Request('/your/url', {
  onSuccess: function(response) {
    ACTIVE_REQUESTS--;
    // Handle the response content...
  }
}));

console.log("there are " + ACTIVE_REQUESTS + " open AJAX requests pending");

With plain script:

使用普通脚本:

interValRef = 0;

interValRef = setInterval("checkState();",100)

function checkState(){
    if(document.readyState == 'complete'){
        clearInterval(interValRef);
        myFunc();
    }
}

Source: Check Pending AJAX requests or HTTP GET/POST request

来源:检查 Pending AJAX 请求或 HTTP GET/POST 请求

回答by falsarella

If you are using JSONP requests, you need to enable the activehandling:

如果您使用的是 JSONP 请求,则需要启用active处理

jQuery.ajaxPrefilter(function( options ) {
    options.global = true;
});


I think that the use of activeis correct, but possiblythe way you have used might return false in the instanceofconditions.

我认为使用的active是正确的,但是可能你使用的方式可能会在返回falseinstanceof条件。

Optionally, see another way to wait for jQuery ajax calls using activein Seleniumtests:

(可选)查看activeSelenium测试中使用的另一种等待 jQuery ajax 调用的方法

browser.wait_for_condition("selenium.browserbot.getCurrentWindow().jQuery.active === 0;", '30000')

回答by Rick Burns

This doesn't work? http://api.jquery.com/ajaxstop/

这行不通? http://api.jquery.com/ajaxstop/

$(document).ajaxStop(function() {
    // Do stuff here...    
});