我有以下代码,但它不能正常工作
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中这样做,但我不断得到证书错误,只是想要更可靠的东西。
提前致谢!
答案 0 :(得分:3)
好的,所以Jason Smiley发布了一个解决方案,但没有解释问题是什么以及解决方案是如何运作的。
第一个问题是传递给executeScript
的脚本没有返回任何内容。 executeScript
做的是在function () { ... }
中包装您传递给它的脚本。因此,$.ajax(...)
形式的某些内容将在浏览器中执行:
function () {
$.ajax(...);
}
这显然不会返回任何内容,如果脚本为2 + 2
它不会返回4
,因为它将执行为:
function () {
2 + 2;
}
传递给executeScript
的脚本必须是return 2 + 2
。
但是,在这里,只需添加此return
即可解决问题。还有一个问题是$.ajax
是异步函数。执行$.ajax
时,会立即返回。传递给它的函数存储在 future 执行中。如果$.ajax
立即返回,那么它返回的值不能可能是给它的任何函数的返回值,因为它们尚未执行 。相反,传递给$.ajax
的函数会执行,无论它们提供给return
的任何内容都无法通过您的代码检索。你唯一能做的就是在函数内部使用你关心的值,或者将它传递给另一个函数。
解决方案是使用专为异步执行而设计的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
作为参数传递,而不是连接到脚本中。我发现这比连接更干净。如果需要解释,arguments
是JavaScript虚拟机自动提供的对象。它包含给函数的参数列表。
是否使用$.ajax
或直接使用XMLHttpRequest
原则是相同的。
答案 1 :(得分:1)
前端开发人员给了我脚本!
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;
}
答案 2 :(得分:-1)
从长远来看,上述代码并没有为我工作。我不记得为什么它不起作用(因为它已经有一段时间了)但是这是我的新答案:
/**
* 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;
}