博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何妥善处理WebBrowser对Javascript的错误问题,阻止JS弹出框,提高用户体验(原创)...
阅读量:6976 次
发布时间:2019-06-27

本文共 3861 字,大约阅读时间需要 12 分钟。

     由于项目需求,最近转战客户端,开始搞浏览器开发。众所周知,现在在微软平台上开发浏览器,最常用的方法就是扩展Webbrowser,但是首先要清楚的是,WebBrowser控件仅仅是对WebBrowser ActiveX 控件提供了托管包装而已(详细了解),要写一个像点样子的浏览器,很多方面还是要自己去扩展的,否则开发出来的也只能是个样子,没多少实际功能。

     本篇随笔重点将介绍如何处理WebBrowser对JS的错误处理问题。

     可能有些朋友看到上句话会觉得,这问题不是很简单嘛,设置一下 ScriptErrorsSuppressed属性不就完了嘛,殊不知这样做,像其他的譬如网页安全验证的弹出框,甚至很多其他网页内部弹出窗口也都被禁止掉了,如此当然是行不通的。可能还会有一部分朋友会说,那可以通过WebBrowser向网页中注入JS错误处理脚本,捕获JS错误,不是也可以嘛。那我会告诉你,这种方法在面对使用很多iframe的网站是也玩完。

     那么接下来,我将介绍,如何更好的避免WebBrowser中的JS错误。

     避免错误,首先要想到办法去捕获错误,查遍了网上的很多资料,发现是要去实现IOleCommandTarget接口,调用接口中的Exec方法来捕获异常,然后解决,当然如果需要去调用IE的一些功能,也得需实现IObjectWithSite接口。

     定义IOleCommandTarget接口、OLECMD类:

public 
static 
class
 NativeMethods 

    {

        public enum OLECMDF
        {
            
// Fields
            OLECMDF_DEFHIDEONCTXTMENU = 0x20,
            OLECMDF_ENABLED = 2,
            OLECMDF_INVISIBLE = 0x10,
            OLECMDF_LATCHED = 4,
            OLECMDF_NINCHED = 8,
            OLECMDF_SUPPORTED = 1
        }
        
public enum OLECMDID
        {
            
// Fields
            OLECMDID_PAGESETUP = 8,
            OLECMDID_PRINT = 6,
            OLECMDID_PRINTPREVIEW = 7,
            OLECMDID_PROPERTIES = 10,
            OLECMDID_SAVEAS = 4,
            OLECMDID_SHOWSCRIPTERROR = 40
        }
        
public enum OLECMDEXECOPT
        {
            
// Fields
            OLECMDEXECOPT_DODEFAULT = 0,
            OLECMDEXECOPT_DONTPROMPTUSER = 2,
            OLECMDEXECOPT_PROMPTUSER = 1,
            OLECMDEXECOPT_SHOWHELP = 3
        }
        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"), ComVisible(true)]
        
public interface IOleCommandTarget
        {
            [return: MarshalAs(UnmanagedType.I4)]
            [PreserveSig]
            
int QueryStatus(ref Guid pguidCmdGroup, int cCmds, [In, Out] NativeMethods.OLECMD prgCmds, [In, Out] IntPtr pCmdText);
            [return: MarshalAs(UnmanagedType.I4)]
            [PreserveSig]
            
int Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, [In, MarshalAs(UnmanagedType.LPArray)] object[] pvaIn, ref int pvaOut);
        }
        [StructLayout(LayoutKind.Sequential)]
        
public class OLECMD
        {
            [MarshalAs(UnmanagedType.U4)]
            
public int cmdID;
            [MarshalAs(UnmanagedType.U4)]
            
public int cmdf;
            
public OLECMD()
            {
            }
        }
        
public const int S_FALSE = 1;
        
public const int S_OK = 0;
        
public static readonly Guid CGID_DocHostCommandHandler = new Guid("f38bc242-b950-11d1-8918-00c04fc2c836");
        
public const int VARIANT_TRUE = -1;
        
public const int VARIANT_FALSE = 0;
        
public const int OLECMDERR_E_NOTSUPPORTED = -2147221244;
    }

       然后定义一个类ExtendedWebBrowserSite,去实现接口:

class
 ExtendedWebBrowserSite : WebBrowserSite, NativeMethods.IOleCommandTarget
        {
            
///
 
<summary>
            
///
 Creates a new instance of the 
<see cref="ExtendedWebBrowserSite"/>
 class
            
///
 
</summary>
            
///
 
<param name="host">
The 
<see cref="ExtendedWebBrowser"/>
 hosting the browser
</param>
            
public
 ExtendedWebBrowserSite(ExtendedWebBrowser host)
                : 
base
(host)
            {
                _host 
=
 host;
            }
            
private
 ExtendedWebBrowser _host;
            
private
 ExtendedWebBrowser Host
            {
                
get
                {
                    
return
 _host;
                }
            }
            
#region
 IOleCommandTarget Members
            
int
 NativeMethods.IOleCommandTarget.QueryStatus(
ref
 Guid pguidCmdGroup, 
int
 cCmds, NativeMethods.OLECMD prgCmds, IntPtr pCmdText)
            {
                
return
 NativeMethods.S_FALSE;
            }
            
int
 NativeMethods.IOleCommandTarget.Exec(
ref
 Guid pguidCmdGroup, 
int
 nCmdID, 
int
 nCmdexecopt, 
object
[] pvaIn, 
ref
 
int
 pvaOut)
            {
                
int
 hResult 
=
 NativeMethods.S_OK;
                
if
 (pguidCmdGroup 
==
 
null
)
                    
return
 hResult;
                
//
 Check for invalid pointers (or get a NullReferenceException on a value type???)
                
//
if (NativeMethods.CGID_DocHostCommandHandler.Equals(pguidCmdGroup))
                {
                    
switch
 (nCmdID)
                    {
                        
case
 (
int
)NativeMethods.OLECMDID.OLECMDID_SHOWSCRIPTERROR:
                            
//
 Hide the dialog
                            pvaOut 
=
 NativeMethods.VARIANT_TRUE;
                            
break
;
                        
default
:
                            hResult 
=
 NativeMethods.OLECMDERR_E_NOTSUPPORTED;
                            
break
;
                    }
                }
                
return
 hResult;
            }
            
#endregion
        }

   } 

    当然这里主要是通过实现IOleCommandTarget.Exec方法去捕获OLECMDID.OLECMDID_SHOWSCRIPTERROR消息,然后避免异常。

      最后在你的扩展的WebBrowser里面重载一下CreateWebBrowserSiteBase方法,完成调用。

        
protected
 
override
 WebBrowserSiteBase CreateWebBrowserSiteBase()
        {
            
return
 
new
 ExtendedWebBrowserSite(
this
);

        } 

    完成以上操作,就可以完全避免WebBrowser中的JS错误发生。

      由于时间有限,并没有多少时间去详细介绍,感兴趣的朋友可以仔细去研究COM组件。

转载于:https://www.cnblogs.com/yangtongnet/archive/2011/08/18/2143420.html

你可能感兴趣的文章
chsop 兼容jquery(解决与transport.js冲突)
查看>>
tar常见文件解压法
查看>>
Oracle 表空间扩容
查看>>
python 查询 elasticsearch 常用方法(Query DSL)
查看>>
wordpress jquery加载如何实现?
查看>>
通过cat /proc/cpuinfo看处理器特点
查看>>
try finally 中的return
查看>>
HBase scan setBatch和setCaching的区别
查看>>
The Ultimate Guide To iPhone Resolutions
查看>>
Ubuntu 12.10 拨号上网及停用方法
查看>>
apkplug插件托管服务简化与简介-05
查看>>
Lucene.net: the main concepts
查看>>
EXP/EXPDP, IMP/IMPDP应用
查看>>
Eclipse create git repository failure(egit)
查看>>
mongodb学习笔记6--杂项与补充
查看>>
solrcloud Read and Write Side Fault Tolerance
查看>>
ADF12C 在线预览PDF文件 afinlineFrame
查看>>
python urllib2 开启调试
查看>>
总结 20 个开发细节
查看>>
面向中小企业的视频云服务 视频托管
查看>>