在 Xamarin 浏览器控件中访问 html 响应内容 [英] Accessing html response content in Xamarin browser control

查看:22
本文介绍了在 Xamarin 浏览器控件中访问 html 响应内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个似乎不寻常的要求,我和我的同事未能在我们的 Xamarin 项目中实施.我们试图做的是动态处理浏览器导航到的任何页面的内容,而不是简单地从它访问的初始 URL 返回的内容.

I have what seems to be an unusual requirement that my colleagues and I haven't been able to implement in our Xamarin project. What we are trying to do is dynamically process the contents of any page that a browser navigates to rather than simply the content returned from the initial URL it accesses.

我已经看到了访问以这种方式返回的内容的解决方案:

I have seen solutions for accessing the content returned this way:

Xamarin:如何从 WebView 中的页面获取 HTML?

然而,只有当浏览器从它所指向的初始 URL 收到第一个 html 响应时,这段代码才会运行.我们需要动态处理浏览器接收到的任何内容,即使它被重定向到不同的 URL 或者用户点击了内容中的链接.我们已经使用 WebBrowser.DocumentCompleted 事件在我们的 .NET 本机 Windows 客户端中实现了这一点,该事件在控件加载内容时引发.除了第一次加载之外,我们没有发现 Xamarin WebViewRendered 加载内容时引发的任何事件或调用的方法,因此我们无法获取后续资源的内容.

However this code will only run when the browser receives the first html response from the initial URL it is pointed to. We need to dynamically process any content the browser receives even if it is redirected to a different URL or if the user clicks on links in the content. We have implemented this in our .NET native Windows clients using the WebBrowser.DocumentCompleted event, which is raised whenever the control loads content. We have not found any event raised or method called when the Xamarin WebViewRendered loads content except on the first load, so we have not been able to get the content of subsequent resources.

总而言之:如何动态获取 Web 浏览器导航到的任何 URL 的内容?答案可以包括可部署到 Android 和 iOS 的 .NET Xamarin 项目中可访问的任何内容,包括第三方开源代码.

To summarize: how can I dynamically get the content of any URL that a web browser navigates to? The answer can include anything accessible in a .NET Xamarin project deployable to Android and iOS including third party open source code.

推荐答案

这两种设备相关的技术都在 HTML 页面完成加载后使用 JavaScript 评估/执行,以便接收整个 html 内容作为 JavaScript 结果(编辑如果您的要求不要求返回整个页面,请使用示例中的 JavaScript).

Both these device-dependent techniques use JavaScript evaluation/execution after the HTML page has finished loading in order for to receive the entire html contents as a JavaScript result (edit the JavaScript in the examples if your requirements to not require the entire page to be return).

您可以通过分配实现 IValueCallback 的子类 WebViewClient 来捕获 WebView 中加载的 html.OnReceiveValue 方法将包含页面加载完成后的 html 内容:

You can capture the loaded html within a WebView by assigning a subclassed WebViewClient that implements IValueCallback. The OnReceiveValue method will contain the html content after the page has finished loading:

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 分配一个 IWKNavigationDelegate 来捕获加载的 html.在它自己的类或包含 WKWebView

Xamarin.iOS

You can capture the loaded html within a WKWebView by assigning a IWKNavigationDelegate to it. Either implement it within its own class or the controller that contains the WKWebView

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 快得多,如果你不需要支持 iOS 7 客户端,我会个人专注于使用WKWebView

Note: This same basic logic can be done with a UIWebView, but WKWebView is so much faster that if you do not need to support iOS 7 clients, I would personally focus on using WKWebView

这篇关于在 Xamarin 浏览器控件中访问 html 响应内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆