您现在的位置是:热点 >>正文

winformwebbrowser关闭来自网页的消息

热点6人已围观

简介WinForm里嵌了个WebBrowser控件,网页一弹alert,那个恼人的对话框就卡在界面中央,标题栏写着“来自网页的消息”,底下就一个“确定”按钮。你点掉它,页面才继续跑。要是网页里循环弹,你手 ...

WinForm里嵌了个WebBrowser控件,闭自网页一弹alert,网页那个恼人的闭自对话框就卡在界面中央,标题栏写着“来自网页的网页消息”,底下就一个“确定”按钮。闭自你点掉它,网页页面才继续跑。闭自要是网页网页里循环弹,你手都点酸。闭自

这问题本质是网页WebBrowser控件把IE的脚本对话框原封不动搬了过来。IE什么德行,闭自它什么德行。网页但WinForm不是闭自浏览器,用户点你的网页程序,不是闭自来跟网页对话框较劲的。我见过一个数据录入系统,网页里每保存一条记录就弹个“保存成功”,操作员一天点掉几百个对话框,手指头都抽筋。

解决办法其实不复杂。核心思路是拦截WebBrowser的脚本对话框事件,自己处理掉,不让它显示出来。具体做法是给WebBrowser控件挂一个事件处理器,处理NewWindow2或者更直接的——处理DocumentCompleted之后,通过HtmlDocument的Window对象挂上Alert事件的拦截。

代码写起来像这样:

webBrowser1.DocumentCompleted += (s, e) => {  if (webBrowser1.Document != null) {  webBrowser1.Document.Window.AttachEventHandler("onbeforeunload", (sender, args) => {  }); // 重点:拦截alert webBrowser1.Document.Window.AttachEventHandler("alert", (sender, args) => {  }); } }; 

但光这么写不够,因为网页里的alert是脚本函数,你得把它替换成空函数。更稳妥的办法是用IHTMLWindow2接口,通过反射或者COM互操作,直接改掉window.alert的实现。

有个土办法也挺管用——在页面加载完成后,往页面里注入一段JavaScript,把alert重写成一个空操作:

webBrowser1.DocumentCompleted += (s, e) => {  if (webBrowser1.Document != null) {  var script = "window.alert = function(msg) {  console.log('alert blocked: ' + msg); };"; webBrowser1.Document.InvokeScript("eval", new object[] {  script }); } }; 

这段代码在页面完全加载后执行,把alert函数替换成只往控制台写日志的空壳。用户界面干干净净,程序后台还能知道网页想弹什么消息——这信息对调试有用。我实际用的时候,会把msg写到一个日志文件里,这样网页报错时我能看到原因,用户却不用被烦。

还有一种情况,网页用的是confirm或者prompt,这俩更麻烦,因为它们在脚本里等着返回值。你光屏蔽不行,脚本会卡住等结果。这时候就得用WebBrowser的ScriptErrorsSuppressed属性,或者重写IDocHostUIHandler接口的ShowMessage方法。后者灵活,能针对不同对话框类型返回不同值——confirm一律返回true,prompt返回空字符串,脚本那边不会死等。

我踩过一个坑:有些网页在onbeforeunload里弹确认框,问“确定要离开吗?”这玩意儿你重写alert没用,得单独处理。用IDocHostUIHandler的ShowMessage拦截时,判断一下消息内容,如果是“确定要离开”之类的,直接返回IDOK。不然用户关窗口时还会被问一次,体验跟浏览器一模一样——你做个WinForm工具,不是来做浏览器的。

其实微软自己也意识到这问题。.NET Framework 4.0以后,WebBrowser控件默认不显示脚本错误对话框,但alert这种主动弹窗它管不着。所以你得自己动手。写代码前先确认你的目标框架,如果用的.NET Core或.NET 5+,WebBrowser控件已经不在默认支持里了,得用WebView2替代——那是后话。

最后提醒一句:屏蔽alert只是治标。网页为什么疯狂弹窗?多半是脚本逻辑有bug,或者它在做轮询提示。你要是有权限改网页源码,从源头改掉比在WinForm里堵截干净得多。但现实里很多网页是第三方写的,你只能在自己这边拦截。那就拦吧,干净利落,别让对话框污染你程序的界面。

Tags:

相关文章

  • 漏洞补丁目录老是会自动生成

    热点

    我电脑的C盘里有个叫PatchCache的文件夹,位置在C:\Windows\SoftwareDistribution\Download。这玩意儿每隔几天就自己长回来,像野草一样。我删了它,系统更新一 ...

    【热点】

    阅读更多
  • 班长穿透眀三角让我爽漫画

    热点

    班长把那张透明三角板举到眼前时,全班都愣住了。不是没见过三角板——数学课上谁没摆弄过那玩意儿?可没人像他那样,把直角边对准窗外的太阳,让折射的光斑在教室后墙上晃出彩虹。他眯着眼,嘴角挂着那种发现了新大 ...

    【热点】

    阅读更多
  • asp本地测试工具

    热点

    ASPActive Server Pages)这东西,二十年前是动态网站的顶梁柱,现在还在维护老系统的程序员,多半都躲不开它。本地测试工具,说白了就是在你自己电脑上模拟一个服务器环境,让ASP代码跑起 ...

    【热点】

    阅读更多


友情链接