WPF WebBrowser的LoadCompleted事件何时触发?该事件是否等待aspx页面中的任何ajax调用完成。
我有一个WPF应用程序,在其中放置了一个WebBrowser控件,并使用Navigate方法加载了一个网页。即使某些ajax调用未初始化/等待,LoadCompleted事件也会触发。
请建议在加载网页100%(包括所有ajax调用)后触发的任何事件。
WPF WebBrowser的LoadCompleted事件何时触发?该事件是否等待aspx页面中的任何ajax调用完成。
我有一个WPF应用程序,在其中放置了一个WebBrowser控件,并使用Navigate方法加载了一个网页。即使某些ajax调用未初始化/等待,LoadCompleted事件也会触发。
请建议在加载网页100%(包括所有ajax调用)后触发的任何事件。
我已经解决了这个问题。
您需要一些第三方程序集:
想法很简单,就是创建一个内存中的代理服务器,并将您的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());
}
}
MainWindow.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.xaml.cs :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
browser.LoadURL("http://google.fr");
}
}
您需要在此应用程序中添加一些管道,以便将请求从应用程序路由和分析到业务类,但这超出了本问题的范围。
当正在导航到的文档下载完成时发生。
这意味着当URL下载完成后,它将触发。它并不意味着任何引用的项目(图像、脚本等)都会触发该事件。
此外,除非您钩入JavaScript引擎本身(我不知道是否可以这样做),以便在回调到Web服务器时得到通知,否则不能保证它是Ajax调用;没有关于调用的标准,通常您使用的各种库的Ajax调用都是不同的。
例如,jQuery使用ajax()
方法,而scriptalicious在内部包装调用,并且不提供直接进行Ajax调用的方法。
或者,您可以直接使用XMLHttpRequest
对象进行调用。
即使您可以将其缩小到使用XMLHttpRequest
的调用,您也不会知道哪些调用是用于Ajax的;可以调用的URL不指示它们是否为Ajax,返回的内容类型(纯文本、XML、JSON)也不指示。
如果你理解了.NET Web模型下面的页面生命周期,你就能看到更大的画面。