UWP应用WebView的InvokeScriptAsync无法执行脚本问题求助
我来帮你梳理下UWP WebView调用脚本没反应的问题,结合我踩过的坑,给你几个核心排查方向:
一、先确认你用的WebView类型,API用错了可不行
UWP里有两种WebView控件,传统WebView和WebView2(基于Edge Chromium),两者执行脚本的API完全不同,别搞混了:
如果是传统WebView(非WebView2):
你得用InvokeScriptAsync方法,而且要通过eval来包裹你的脚本代码,示例:
private async void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args) { if (args.IsSuccess) { // 执行alert脚本,必须用eval包裹 await sender.InvokeScriptAsync("eval", new string[] { "alert('测试弹窗');" }); } }
另外,传统WebView默认不会弹出原生alert窗口,得通过ScriptNotify事件来接收脚本的通知:
// 先在构造函数或XAML里绑定事件 webView.ScriptNotify += WebView_ScriptNotify; private async void WebView_ScriptNotify(object sender, NotifyEventArgs e) { // 脚本里调用window.external.notify('内容'),就能在这里收到并弹出对话框 await new MessageDialog(e.Value).ShowAsync(); }
这时候一定要确保Package.appxmanifest里的Content URI对应的WinRT access设为Allow,不然window.external.notify根本触发不了事件。
如果是WebView2:
WebView2得等CoreWebView2初始化完成再执行脚本,别只依赖NavigationCompleted,建议监听CoreWebView2InitializationCompleted事件:
private async void WebView2_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) { if (e.IsSuccess) { // 先开启默认脚本弹窗权限(alert/confirm这些) webView2.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = true; // 执行脚本 await webView2.CoreWebView2.ExecuteScriptAsync("alert('测试弹窗');"); } }
二、NavigationCompleted不代表页面完全就绪
NavigationCompleted触发只是主文档加载完了,但页面里的动态脚本(比如AJAX加载的JS、延迟执行的代码)可能还没初始化。如果你的脚本依赖页面内的JS对象,得等DOM完全准备好:
传统WebView:
可以先注入一个监听DOMContentLoaded的脚本,等DOM就绪后通过ScriptNotify通知C#端再执行目标脚本:
await webView.InvokeScriptAsync("eval", new string[] { @" document.addEventListener('DOMContentLoaded', function() { window.external.notify('DOM加载完成,可以执行脚本了'); }); " });
然后在ScriptNotify事件里收到通知后,再运行你的业务脚本。
WebView2:
用AddScriptToExecuteOnDocumentCreatedAsync方法,确保脚本在DOM准备好时自动执行:
await webView2.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(@" alert('DOM就绪时自动执行'); ");
三、Content URI配置要精准
你说加了http://www.facebook.com和https://www.facebook.com,但要注意:
- 必须加通配符覆盖所有子页面,比如
https://www.facebook.com/*,不然跳转到https://www.facebook.com/profile这类子路径时,权限直接失效。 - 在Package.appxmanifest的Content URIs里,把WinRT access设为
Allow for all domains(或者对应域名的允许访问),别留空或者设成拒绝。
四、目标页面的CSP可能在搞事情
像Facebook这种大站有严格的内容安全策略(CSP),可能会阻止内联脚本、eval甚至alert的执行。你可以打开开发者工具看看控制台有没有报错:
- 传统WebView:调用
webView.OpenDevToolsWindow()打开调试工具,检查控制台的CSP相关错误。 - WebView2:调用
webView2.CoreWebView2.OpenDevToolsWindow()查看报错。
如果是CSP限制导致的,那大概率没法在这类网站上执行自定义脚本——毕竟这违反了人家的安全政策。
内容的提问来源于stack exchange,提问作者MusicAndCode

