Java Selenium从WebDriver获取HTML(或JSON)响应

Java Selenium从WebDriver获取HTML(或JSON)响应,java,ajax,json,selenium,selenium-webdriver,Java,Ajax,Json,Selenium,Selenium Webdriver,我有以下代码,但它不工作 public static String getHTMLResponse(String url){ String body = (String) js.executeScript("$.ajax({url:\""+ url + "\", success:function(result){ return result;}});"); return body; } 由于某些原因,它总是返回null 有人在webdriver中尝试过从ajax获得CURL响应吗

我有以下代码,但它不工作

public static String getHTMLResponse(String url){
   String body = (String) js.executeScript("$.ajax({url:\""+ url + "\", success:function(result){ return result;}});");
    return body;
}
由于某些原因,它总是返回null

有人在webdriver中尝试过从ajax获得CURL响应吗?我以前在java中做过这件事,但我经常会遇到证书错误,我只是想要一些更可靠的东西


提前谢谢

前端开发人员给了我脚本

   public static String getHTMLResponse(String url){
      String body = (String) js.executeAsyncScript(
            "var callback = arguments[arguments.length - 1];" +
                    "var xhr = new XMLHttpRequest();" +
                    "xhr.open('GET', '"+ url + "', true);" +
                    "xhr.onreadystatechange = function() {" +
                    "  if (xhr.readyState == 4) {" +
                    "    callback(xhr.responseText);" +
                    "  }" +
                    "};" +
                    "xhr.send();");
      return body;
  }

好的,Jason Smiley发布了一个解决方案,但没有解释问题是什么以及解决方案是如何工作的

第一个问题是传递给
executeScript
的脚本没有返回任何内容,句号。
executeScript
所做的是将传递给它的脚本包装在
function(){…}
中。因此,某种形式的
$.ajax(…)
将在浏览器中执行,如下所示:

function () {
    $.ajax(...);
}
这显然不会以与脚本为
2+2
时不会返回
4
相同的方式返回任何内容,因为它将按以下方式执行:

function () {
    2 + 2;
}
传递给
executeScript
的脚本必须是
return2+2

然而,在这里,仅仅添加这个
返回值
并不能解决问题。还有一个问题是,
$。ajax
是一个异步函数。当执行
$.ajax
时,它会立即返回。传递给它的函数被存储起来以备将来执行。如果
$.ajax
立即返回,那么它返回的值不可能是给定给它的任何函数的返回值,因为这些函数尚未执行。相反,则传递给
$的函数会执行,无论它们给
返回的是什么,代码都无法检索它们。您唯一能做的就是在函数本身内部使用您关心的值,或者将其传递给另一个函数

解决方案是使用设计用于异步执行的
executeAsyncScript
。此函数与
executeScript
类似,但添加了一个参数,该参数是一个回调函数,应在脚本完成执行后调用,并应使用希望
executeAsyncScript
返回的值调用该函数

请注意,绝对没有必要放弃
$.ajax
。以下方面应起作用:

public static String getHTMLResponse(String url){
    String body = (String) js.executeAsyncScript(
        "var url = arguments[0];" + 
        "var callback = arguments[1];" +
        "$.ajax({url: url, success: callback});", 
        url);
    return body;
}
注意,我设置了这段代码,以便
url
作为参数传递,而不是连接到脚本中。我发现这比串联更干净。如果需要对此进行解释,
参数
是JavaScript虚拟机自动提供的对象。它保存给定给函数的参数列表


无论是使用
$.ajax
还是直接使用
XMLHttpRequest
,原则都是一样的。

从长远来看,上述代码对我来说并不起作用。我不记得为什么它不起作用(因为它已经有一段时间了),但下面是我的新答案:

/**
 * CURLs the page passed in for the HTML response. Uses AJAX so base domain must match the url.
 *
 * Special exception for MkItem requests
 *
 * @param url   - URL to CURL
 * @param debug - Pass in true for debug output.
 * @return HTML result as a string.
 * @throws IOException
 */
public static String getHTMLResponse(String url, boolean debug) throws IOException {
    if(debug){System.out.println("Making request to:\n\n" + url);}
    String body = "";

    try{
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }

            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        }
        };

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    }catch (Exception e){
        Assert.fail("Exception thrown trying to perform GET request. " + e.getMessage());
    }
    URLConnection con;

    //If not a secure page, use cURL
        /*if(!url.contains("https://")){*/
        try{
            URL temp = new URL(url);
            con = temp.openConnection();
            InputStream in = con.getInputStream();
            String encoding = con.getContentEncoding();
            encoding = encoding == null ? "UTF-8" : encoding;
            body = IOUtils.toString(in, encoding);
        } catch (MalformedURLException e){
            Assert.fail("URL wasn't passed in correctly - " + e.getMessage());
        } catch (IOException e){
            throw e;
        }

    if(debug){ System.out.println("Body:\n"+ body); }

    Assert.assertNotNull("Body returned null for " + url, body);

    return body;
}

谢谢你,路易斯!我没有在票上提到这一点,但实际上我有一些OP脚本的变体。我能看出什么也没有被归还,我想我不知道为什么什么也没有被归还。例如,为什么“success:callback”有效而“success:returnarguments[1]”或“success:function(){returnarguments[1]}无效。很确定其中一个没有编译,但我已经记不起是哪一个了,事实上,我不得不改变它。将添加一个新的应答器注意,我现在刚刚关闭安全证书检查。减少了与HTTP和HTTPS功能相关的麻烦。这是如何回答您最初的问题的?您在问题中没有提到任何关于ssl的内容。