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
How to checkif there are pending requests (Ajax and its variants) from browser
提问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 请求,但不适用于任何带有 jQuery 库变体的类似请求。
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
回答by falsarella
If you are using JSONP requests, you need to enable the active
handling:
如果您使用的是 JSONP 请求,则需要启用active
处理:
jQuery.ajaxPrefilter(function( options ) {
options.global = true;
});
I think that the use of active
is correct, but possiblythe way you have used might return false in the instanceof
conditions.
我认为使用的active
是正确的,但是可能你使用的方式可能会在返回falseinstanceof
条件。
Optionally, see another way to wait for jQuery ajax calls using active
in Selenium
tests:
(可选)查看active
在Selenium
测试中使用的另一种等待 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...
});