JavaFX WebView - 如何捕获 URL 加载?
JavaFX WebView - How to capture the URL loading?
我目前正在使用 GluonHQ (JavaFXPorts) 开发一个应用程序,我正在使用 WebView 加载一些 Internet 页面。当我加载 https://signin.ebay.com/ 页面时,我在控制台上看到以下消息
[WebEngine] I can handle this protocol for https://signin.ebay.com/
ES2ResourceFactory: Prism - createStockShader: AlphaTexture_RadialGradient.frag
[WebEngine] I can handle this protocol for https://www.ebay.com/ws/
[WebEngine] I can't handle this protocol for about:blank
[WebEngine] I can handle this protocol for https://www.ebay.com/t_n.html?org_id=usllpic0&session_id=f5b8d48d1670a9cce3431193fffe9431&suppressFlash=true
[WebEngine] I can't handle this protocol for about:blank
2018-12-28 18:49:53 Watchdog[2021:302159] WF: _userSettingsForUser mobile: {
filterBlacklist = (
);
filterWhitelist = (
);
restrictWeb = 1;
useContentFilter = 0;
useContentFilterOverrides = 0;
whitelistEnabled = 0;
}
2018-12-28 18:49:53 Watchdog[2021:302159] WF: _WebFilterIsActive returning: NO
2018-12-28 18:49:55 Watchdog[2021:302159] CoreAnimation: [EAGLContext renderbufferStorage:fromDrawable:] was called from a non-main thread in an implicit transaction! Note that this may be unsafe without an explicit CATransaction or a call to [CATransaction flush].
[WebEngine] I can handle this protocol for https://src.ebay-us.com/fp/top_fp.html;CIS3SID=08561C52B9A266EE68861D27BCE99A74?org_id=usllpic0&session_id=f5b8d48d1670a9cce3431193fffe9431&nonce=b6190f233a143165
应用程序似乎也调用了其他网站的负载,但我找不到捕获它们的方法。我也试过在状态改变时获取位置
webEngine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
System.out.println("State(" + newState + "): " + webEngine.getLocation());
}
但没有任何成功。在第一次加载站点之前,位置似乎为空,然后返回原始 URL,即 https://signin.ebay.com。我相信额外出现的 "protocols" 是 AJAX 的一部分。任何人都知道如何实现侦听器来捕获这些信息?
[WebEngine] I can handle this protocol for https://signin.ebay.com/
State(SCHEDULED): null
State(RUNNING): null
ES2ResourceFactory: Prism - createStockShader: AlphaTexture_RadialGradient.frag
[WebEngine] I can handle this protocol for https://www.ebay.com/ws/
[WebEngine] I can't handle this protocol for about:blank
State(SCHEDULED): null
State(RUNNING): null
State(SUCCEEDED): null
[WebEngine] I can handle this protocol for https://www.ebay.com/t_n.html?org_id=usllpic0&session_id=f5c7ab7f1670a9ccaac210b2ffe8709e&suppressFlash=true
State(SCHEDULED): https://signin.ebay.com
State(RUNNING): https://signin.ebay.com
[WebEngine] I can't handle this protocol for about:blank
State(SCHEDULED): https://signin.ebay.com
State(RUNNING): https://signin.ebay.com
State(SUCCEEDED): https://signin.ebay.com
2018-12-28 19:06:05 Watchdog[2050:306357] WF: _userSettingsForUser mobile: {
filterBlacklist = (
);
filterWhitelist = (
);
restrictWeb = 1;
useContentFilter = 0;
useContentFilterOverrides = 0;
whitelistEnabled = 0;
}
2018-12-28 19:06:05 Watchdog[2050:306357] WF: _WebFilterIsActive returning: NO
2018-12-28 19:06:09 Watchdog[2050:306357] CoreAnimation: [EAGLContext renderbufferStorage:fromDrawable:] was called from a non-main thread in an implicit transaction! Note that this may be unsafe without an explicit CATransaction or a call to [CATransaction flush].
[WebEngine] I can handle this protocol for https://src.ebay-us.com/fp/top_fp.html;CIS3SID=D553152B77DCBE35641E606BDAB6AFDA?org_id=usllpic0&session_id=f5c7ab7f1670a9ccaac210b2ffe8709e&nonce=f3e7bb25c25eb5c1
State(SCHEDULED): https://signin.ebay.com
State(RUNNING): https://signin.ebay.com
State(SUCCEEDED): https://signin.ebay.com
作为此类似 的后续内容,其中指出:
With JavaFXPorts, on mobile (both Android and iOS) the WebView control is not the JavaFX built-in control but the native control
在原生中可以看到这个方法implementation:
- (BOOL)webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *url = [[request URL] absoluteString];
JNIEnv *env = [self getJNIEnv];
if (env != NULL) {
jstring jUrl = createJString(env, url);
(*env)->CallVoidMethod(env, jObject, jmidHasAppProtocolHandler, jUrl);
...
}
进入 JavaFX WebEngine
callback:
/**
* check if there is a handler registered for dealing with this protocol.
*/
boolean hasAppProtocolHandler(String url) {
boolean answer = false;
try {
URL u = newURL(null, url);
System.out.println ("[WebEngine] I can handle this protocol for "+url);
u.openConnection();
// location.set(url);
answer = true;
}
// catch (MalformedURLException e) {
catch (Exception e) {
System.out.println ("[WebEngine] I can't handle this protocol for "+url);
// no handler known for this protocol
}
return answer;
}
这解释了控制台打印输出:什么时候可以打开URL,或者什么时候出现异常。所有不同的结果似乎都与本机浏览器如何处理 URL 加载有关,但您只会在 JavaFX 层中得到一个回声。
关于使用WebEngine::getLocation
,请注意,只有当本机浏览器完成加载一个Url时,才会发回通知并且location is set:
void notifyLoadFinished(String loc, String content) {
synchronized (loadedLock) {
this.pageContent = "<html>"+content+"</html>";
loaded = true;
updateProgress(1.0);
updateState(Worker.State.SUCCEEDED);
location.set(loc); // <--- location from native browser is set
document.invalidate(true);
if (pageListener != null) {
pageListener.onLoadFinished();
}
}
}
我建议您查看 WebView
和 iOS 平台的 WebEngine
的 JavaFX 代码,看看可以做什么,不能做什么。
例如,脚本引擎可以工作,因此您可以execute一些脚本来报告一些信息。
我目前正在使用 GluonHQ (JavaFXPorts) 开发一个应用程序,我正在使用 WebView 加载一些 Internet 页面。当我加载 https://signin.ebay.com/ 页面时,我在控制台上看到以下消息
[WebEngine] I can handle this protocol for https://signin.ebay.com/
ES2ResourceFactory: Prism - createStockShader: AlphaTexture_RadialGradient.frag
[WebEngine] I can handle this protocol for https://www.ebay.com/ws/
[WebEngine] I can't handle this protocol for about:blank
[WebEngine] I can handle this protocol for https://www.ebay.com/t_n.html?org_id=usllpic0&session_id=f5b8d48d1670a9cce3431193fffe9431&suppressFlash=true
[WebEngine] I can't handle this protocol for about:blank
2018-12-28 18:49:53 Watchdog[2021:302159] WF: _userSettingsForUser mobile: {
filterBlacklist = (
);
filterWhitelist = (
);
restrictWeb = 1;
useContentFilter = 0;
useContentFilterOverrides = 0;
whitelistEnabled = 0;
}
2018-12-28 18:49:53 Watchdog[2021:302159] WF: _WebFilterIsActive returning: NO
2018-12-28 18:49:55 Watchdog[2021:302159] CoreAnimation: [EAGLContext renderbufferStorage:fromDrawable:] was called from a non-main thread in an implicit transaction! Note that this may be unsafe without an explicit CATransaction or a call to [CATransaction flush].
[WebEngine] I can handle this protocol for https://src.ebay-us.com/fp/top_fp.html;CIS3SID=08561C52B9A266EE68861D27BCE99A74?org_id=usllpic0&session_id=f5b8d48d1670a9cce3431193fffe9431&nonce=b6190f233a143165
应用程序似乎也调用了其他网站的负载,但我找不到捕获它们的方法。我也试过在状态改变时获取位置
webEngine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
System.out.println("State(" + newState + "): " + webEngine.getLocation());
}
但没有任何成功。在第一次加载站点之前,位置似乎为空,然后返回原始 URL,即 https://signin.ebay.com。我相信额外出现的 "protocols" 是 AJAX 的一部分。任何人都知道如何实现侦听器来捕获这些信息?
[WebEngine] I can handle this protocol for https://signin.ebay.com/
State(SCHEDULED): null
State(RUNNING): null
ES2ResourceFactory: Prism - createStockShader: AlphaTexture_RadialGradient.frag
[WebEngine] I can handle this protocol for https://www.ebay.com/ws/
[WebEngine] I can't handle this protocol for about:blank
State(SCHEDULED): null
State(RUNNING): null
State(SUCCEEDED): null
[WebEngine] I can handle this protocol for https://www.ebay.com/t_n.html?org_id=usllpic0&session_id=f5c7ab7f1670a9ccaac210b2ffe8709e&suppressFlash=true
State(SCHEDULED): https://signin.ebay.com
State(RUNNING): https://signin.ebay.com
[WebEngine] I can't handle this protocol for about:blank
State(SCHEDULED): https://signin.ebay.com
State(RUNNING): https://signin.ebay.com
State(SUCCEEDED): https://signin.ebay.com
2018-12-28 19:06:05 Watchdog[2050:306357] WF: _userSettingsForUser mobile: {
filterBlacklist = (
);
filterWhitelist = (
);
restrictWeb = 1;
useContentFilter = 0;
useContentFilterOverrides = 0;
whitelistEnabled = 0;
}
2018-12-28 19:06:05 Watchdog[2050:306357] WF: _WebFilterIsActive returning: NO
2018-12-28 19:06:09 Watchdog[2050:306357] CoreAnimation: [EAGLContext renderbufferStorage:fromDrawable:] was called from a non-main thread in an implicit transaction! Note that this may be unsafe without an explicit CATransaction or a call to [CATransaction flush].
[WebEngine] I can handle this protocol for https://src.ebay-us.com/fp/top_fp.html;CIS3SID=D553152B77DCBE35641E606BDAB6AFDA?org_id=usllpic0&session_id=f5c7ab7f1670a9ccaac210b2ffe8709e&nonce=f3e7bb25c25eb5c1
State(SCHEDULED): https://signin.ebay.com
State(RUNNING): https://signin.ebay.com
State(SUCCEEDED): https://signin.ebay.com
作为此类似
With JavaFXPorts, on mobile (both Android and iOS) the WebView control is not the JavaFX built-in control but the native control
在原生中可以看到这个方法implementation:
- (BOOL)webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *url = [[request URL] absoluteString];
JNIEnv *env = [self getJNIEnv];
if (env != NULL) {
jstring jUrl = createJString(env, url);
(*env)->CallVoidMethod(env, jObject, jmidHasAppProtocolHandler, jUrl);
...
}
进入 JavaFX WebEngine
callback:
/**
* check if there is a handler registered for dealing with this protocol.
*/
boolean hasAppProtocolHandler(String url) {
boolean answer = false;
try {
URL u = newURL(null, url);
System.out.println ("[WebEngine] I can handle this protocol for "+url);
u.openConnection();
// location.set(url);
answer = true;
}
// catch (MalformedURLException e) {
catch (Exception e) {
System.out.println ("[WebEngine] I can't handle this protocol for "+url);
// no handler known for this protocol
}
return answer;
}
这解释了控制台打印输出:什么时候可以打开URL,或者什么时候出现异常。所有不同的结果似乎都与本机浏览器如何处理 URL 加载有关,但您只会在 JavaFX 层中得到一个回声。
关于使用WebEngine::getLocation
,请注意,只有当本机浏览器完成加载一个Url时,才会发回通知并且location is set:
void notifyLoadFinished(String loc, String content) {
synchronized (loadedLock) {
this.pageContent = "<html>"+content+"</html>";
loaded = true;
updateProgress(1.0);
updateState(Worker.State.SUCCEEDED);
location.set(loc); // <--- location from native browser is set
document.invalidate(true);
if (pageListener != null) {
pageListener.onLoadFinished();
}
}
}
我建议您查看 WebView
和 iOS 平台的 WebEngine
的 JavaFX 代码,看看可以做什么,不能做什么。
例如,脚本引擎可以工作,因此您可以execute一些脚本来报告一些信息。