2014-10-06 204 views
2

我有以下的代碼,但它不工作硒webdriver的從

public static String getHTMLResponse(String url){ 
    String body = (String) js.executeScript("$.ajax({url:\""+ url + "\", success:function(result){ return result;}});"); 
    return body; 
} 

出於某種原因,這總是返回null獲得HTML(或JSON)響應。

有沒有人試圖讓從阿賈克斯在webdriver的捲曲反應?我之前是在java中這樣做的,但我不斷地收到證書錯誤,只想要更可靠的東西。

提前致謝!

回答

-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; 
} 
+0

請注意,我現在只是關閉安全證書檢查。減少與HTTP和HTTPS功能相關的麻煩。 – 2015-01-30 16:26:17

+0

這是如何回答你的原始問題?你沒有提到有關ssl的問題。 – tanjir 2016-01-27 16:37:00

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; 
    } 
+0

嗨Jason是上述代碼爲您工作。 – selva 2014-10-07 06:56:30

+0

實際上不再 - 我必須改變它。將添加一個新的答案 – 2015-01-29 15:43:26

3

好的,Jason Smiley發佈了一個解決方案,但沒有解釋問題是什麼以及解決方案如何工作。

的第一個問題是,傳遞給executeScript腳本不返回任何內容,期限。 executeScript所做的是將您傳遞給它的腳本封裝在function() { ... }中。所以形式$.ajax(...)的東西會因爲這在瀏覽器中執行:

function() { 
    $.ajax(...); 
} 

這顯然不會以同樣的方式,如果腳本是2 + 2它不會返回4,因爲它會爲執行任何回報:

function() { 
    2 + 2; 
} 

傳遞給executeScript該腳本將不得不return 2 + 2

然而,在這裏,只需添加這return不會解決問題。還有一個額外的問題,$.ajax是一個異步功能。當$.ajax執行時,它立即返回。傳遞給它的函數存儲爲未來執行。如果$.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的原理是相同的。

+0

謝謝路易斯!我沒有在票證中提到這一點,但我實際上有一些OP腳本的變體。我可以說沒有任何東西被返回,我想我不知道爲什麼沒有返回。例如,爲什麼「success:callback」工作,而不是「success:return arguments [1]」或「success:function(){return arguments [1]}」。很確定其中一個沒有編譯,但我不記得哪一個大聲笑 – 2014-10-07 20:11:06