访问Xamarin浏览器控件中的html响应内容
本文关键字:html 响应 Xamarin 浏览器 控件 访问 | 更新日期: 2023-09-27 17:59:55
我有一个不寻常的需求,我和我的同事在Xamarin项目中未能实现。我们试图做的是动态处理浏览器导航到的任何页面的内容,而不是简单地处理从其访问的初始URL返回的内容。
我看到了访问以这种方式返回的内容的解决方案:
Xamarin:如何在WebView中从页面获取HTML?
然而,只有当浏览器从其指向的初始URL接收到第一个html响应时,此代码才会运行。我们需要动态处理浏览器接收到的任何内容,即使它被重定向到不同的URL或用户点击了内容中的链接。我们已经在.NET本机Windows客户端中使用WebBrowser.DocumentCompleted事件实现了这一点,每当控件加载内容时就会引发该事件。除了第一次加载外,我们没有发现Xamarin WebViewRendered加载内容时引发的任何事件或调用的方法,因此我们无法获取后续资源的内容。
总结一下:如何动态获取web浏览器导航到的任何URL的内容?答案可以包括可部署到Android和iOS的.NET Xamarin项目中可访问的任何内容,包括第三方开源代码。
这两种依赖于设备的技术都在HTML页面加载完成后使用JavaScript评估/执行,以便接收整个HTML内容作为JavaScript结果(如果您需要不返回整个页面,请编辑示例中的JavaScript)。
Xamarin.Android
您可以通过分配实现IValueCallback
的子类WebViewClient
来捕获WebView
中加载的html。OnReceiveValue
方法将在页面加载完成后包含html内容:
示例WebViewClient
类:
public class EmbeddedWebViewClient : WebViewClient, IValueCallback
{
public EmbeddedWebViewClient(WebView view)
{
view.Settings.JavaScriptEnabled = true;
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
Log.Info("SO", $"Page loaded from: {url}");
view.EvaluateJavascript("(function() { return ('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>'); })();", this);
}
public void OnReceiveValue(Java.Lang.Object value)
{
// "value" holds the html contents of the loaded page
Log.Debug("SO", ((string)value).Substring(0, 40));
}
}
WebViewClient使用示例:
WebView webview = FindViewById<WebView>(Resource.Id.webview);
webview.SetWebViewClient(new EmbeddedWebViewClient(webview));
webview.LoadUrl("https://xamarin.com");
Xamarin.iOS
您可以在WKWebView
中捕获加载的html,方法是将IWKNavigationDelegate
分配给它。在它自己的类或包含WKWebView
的控制器中实现它
示例IWKNavigationDelegate
实现:
public class NavigationDelegate : NSObject, IWKNavigationDelegate
{
[Export("webView:didFinishNavigation:")]
public async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
var content = await webView.EvaluateJavaScriptAsync("(function() { return ('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>'); })();");
var html = FromObject(content);
Console.WriteLine((html.ToString()).Substring(0, 40));
}
}
WKWebView使用示例:
wkwebview = new WKWebView(UIScreen.MainScreen.Bounds, new WKWebViewConfiguration());
wkwebview.NavigationDelegate = new NavigationDelegate();
Add(wkwebview);
wkwebview.LoadRequest(new NSUrlRequest(new Uri("https://xamarin.com")));
注意:UIWebView
也可以实现同样的基本逻辑,但WKWebView
要快得多,如果你不需要支持iOS7客户端,我个人会专注于使用WKWebView