WPF浏览器的LoadCompleted事件

本文关键字:事件 LoadCompleted 浏览器 WPF | 更新日期: 2023-09-27 18:06:26

WPF浏览器的LoadCompleted事件何时触发?此事件是否等待任何ajax调用在aspx页面中完成。

我有一个wpf应用程序,其中一个网页浏览器控件放置在窗口窗体和使用导航方法加载的网页。LoadCompleted事件触发,即使一些ajax调用没有初始化或等待。

请建议加载网页100%后触发的任何事件,包括所有ajax调用。

WPF浏览器的LoadCompleted事件

我已经能解决这样的问题了。

你将需要一些第三方组件:

  1. FiddlerCore:将作为一个http代理,嵌入到你的应用程序
  2. Awesomium.net:一个WebBrowser控件,与chromium引擎一起工作。我选择这个引擎是因为它允许为应用程序指定一个代理服务器。

这个想法,正如你所猜到的,是创建一个内存中的代理服务器,并将你的web浏览器控制重定向到这个代理。

然后,FiddlerCore发布一些事件,您可以在其中分析请求/响应,特别是主体。

作为代理,所有通信,包括Ajax调用、Flash调用等,都由代理路由。

如果它可以帮助,一个小代码,帮助我原型这个行为:

App.cs:

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        BootStrap();
        base.OnStartup(e);
    }
    private void BootStrap()
    {
        SetupInternalProxy();
        SetupBrowser();
    }
    private static void SetupBrowser()
    {
        // We may be a new window in the same process.
        if (!WebCore.IsRunning)
        {
            // Setup WebCore with plugins enabled.
            WebCoreConfig config = new WebCoreConfig
            {
                ProxyServer = "http://127.0.0.1:" + FiddlerApplication.oProxy.ListenPort.ToString(),
                EnablePlugins = true,
                SaveCacheAndCookies = true
            };
            WebCore.Initialize(config);
        }
        else
        {
            throw new InvalidOperationException("WebCore should be already running");
        }
    }
    private void SetupInternalProxy()
    {
        FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
        FiddlerApplication.Log.OnLogString += (o, s) => Debug.WriteLine(s);
        FiddlerCoreStartupFlags oFCSF = FiddlerCoreStartupFlags.Default;
        //this line is important as it will avoid changing the proxy for the whole system.
        oFCSF = (oFCSF & ~FiddlerCoreStartupFlags.RegisterAsSystemProxy);
        FiddlerApplication.Startup(
            0,
            oFCSF
            );
    }
    private void FiddlerApplication_AfterSessionComplete(Session oSession)
    {
        Debug.WriteLine(oSession.GetResponseBodyAsString());
    }
}

主窗口。xaml:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1" 
        xmlns:Custom="http://schemas.awesomium.com/winfx" 
        x:Class="WpfApplication1.MainWindow"
        Title="MainWindow" Height="350" Width="525" Loaded="MainWindow_Loaded">
    <Grid>
        <Custom:WebControl Name="browser"/>
    </Grid>
</Window>

最后,mainwindow . example .cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        browser.LoadURL("http://google.fr");
    }
}

为了路由和分析从应用程序到业务类的请求,你必须在这个应用程序中添加一些管道,但这超出了这个问题的范围。

LoadComplete事件的文档说明:

当导航到的文档下载完成时发生。

这意味着当url下载完成后,它将被触发。这并不意味着任何引用的项都会触发事件(图像,脚本等)。

此外,除非你钩到JavaScript引擎本身(我不知道如果你能做到)被通知当调用返回到web服务器,它不能保证这是一个Ajax调用;在调用方面没有标准,而且对Ajax的调用通常在您使用的各种库之间是不同的。

例如,jQuery使用ajax()方法,而scriptalicious在内部封装调用,并且不给您直接进行Ajax调用的方法。

也可以直接使用XMLHttpRequest对象进行呼叫。

即使您可以将其缩小到使用XMLHttpRequest的调用,您也不知道哪些调用是针对Ajax的;可以调用的url并不指示它们是否是Ajax,也不指示返回的内容类型(纯文本、XML、JSON)。

如果你理解了下面的。net web模型的页面生命周期,你就会有更大的了解。

  1. Page_PreInit
  2. 列表项
  3. Page_Init
  4. Page_InitComplete
  5. Page_PreLoad
  6. Page_Load
  7. <
  8. 控制事件/gh>
  9. Page_LoadComplete
  10. Page_PreRender
  11. SaveViewState
  12. Page_Render
  13. Page_Unload