好的,所以 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,原理都是一样的。