WebView2调用Reload后ExecuteScriptAsync返回null问题咨询
WebView2刷新后ExecuteScriptAsync返回null的问题解决
问题描述
我正在开发一个使用WebView2控件的Windows Forms应用,用于展示网页并检测页面变化。设置了每10分钟触发一次的定时器,执行以下代码片段:
private async void timer1_Tick(object sender, EventArgs e) { webView21.Reload(); String html = await webView21.ExecuteScriptAsync("document.documentElement.outerHTML;"); SHA256 hash = SHA256.Create(); String thisTimeHash = GetHash(hash, html); richTextBox1.AppendText(DateTime.Now.ToString("u") + " " + thisTimeHash + Environment.NewLine); }
但调用webView21.Reload()刷新页面后,webView21.ExecuteScriptAsync返回null;若注释掉webView21.Reload(),则能正常获取页面HTML。请问哪里操作有误,该如何解决?
问题原因
webView21.Reload()是异步触发页面刷新的,调用后页面并不会立刻加载完成。你紧接着执行ExecuteScriptAsync时,页面还处于加载状态,DOM尚未完全构建,所以脚本无法获取到有效的HTML,返回null。
解决方法
方法一:监听NavigationCompleted事件(推荐)
利用WebView2的NavigationCompleted事件,在页面导航完成且加载成功后,再执行获取HTML的脚本,这是最可靠的方式。
- 修改定时器的Tick事件,只负责触发页面刷新:
private void timer1_Tick(object sender, EventArgs e) { webView21.Reload(); }
- 添加
NavigationCompleted事件的处理方法:
private async void webView21_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e) { // 仅在导航成功时执行后续逻辑 if (e.IsSuccess) { string html = await webView21.ExecuteScriptAsync("document.documentElement.outerHTML;"); using (SHA256 hash = SHA256.Create()) { string thisTimeHash = GetHash(hash, html); richTextBox1.AppendText($"{DateTime.Now.ToString("u")} {thisTimeHash}{Environment.NewLine}"); } } }
- 在窗体初始化时注册该事件(比如构造函数中):
public YourFormName() { InitializeComponent(); // 注册NavigationCompleted事件 webView21.NavigationCompleted += webView21_NavigationCompleted; }
方法二:等待页面加载完成(不推荐)
如果不想使用事件,可以在Reload后等待页面加载状态变为完成,但这种方式可能因网络或页面加载速度问题导致不稳定,且容易阻塞UI线程,仅作参考:
private async void timer1_Tick(object sender, EventArgs e) { webView21.Reload(); // 等待页面加载完成 while (webView21.CoreWebView2 == null || webView21.CoreWebView2.IsLoading) { await Task.Delay(100); } string html = await webView21.ExecuteScriptAsync("document.documentElement.outerHTML;"); using (SHA256 hash = SHA256.Create()) { string thisTimeHash = GetHash(hash, html); richTextBox1.AppendText($"{DateTime.Now.ToString("u")} {thisTimeHash}{Environment.NewLine}"); } }
注意:方法二中的循环等待可能会导致UI卡顿,优先使用方法一的事件监听方式。
内容的提问来源于stack exchange,提问作者Peter Franks
相关产品推荐
相关产品推荐

