在 WebBrowser 控件中禁用 JavaScript 错误

Posted

技术标签:

【中文标题】在 WebBrowser 控件中禁用 JavaScript 错误【英文标题】:Disable JavaScript error in WebBrowser control 【发布时间】:2011-01-29 09:37:24 【问题描述】:

我正在开发一个带有导航到共享点站点的 WebBrowser 控件的 Windows 应用程序。 我的问题是我收到 javascript 错误。

如何禁用 JavaScript 错误?我不希望它们弹出。

【问题讨论】:

这个拯救了我的一天。真的…… 【参考方案1】:
webBrowser.ScriptErrorsSuppressed = true;

【讨论】:

谢谢伙计,为我节省了很多时间! 为了记录,这个属性在后台执行 this.AxIWebBrowser2.Silent = true; 还应该添加 this.AxIWebBrowser2.Silent = true 抑制所有弹出窗口,而不仅仅是脚本错误,因此 WebBrowser.ScriptErrorsSuppressd 似乎命名不正确。 谁能告诉我,我应该在哪里写这行代码?请帮忙!! 这将删除所有弹出窗口,包括登录框。最好是使用 redclax 所做的事情【参考方案2】:

这会禁用脚本错误并禁用其他窗口。例如 NTLM 登录窗口或客户端证书接受窗口。下面将仅抑制 javascript 错误。

// Hides script errors without hiding other dialog boxes.
private void SuppressScriptErrorsOnly(WebBrowser browser)

    // Ensure that ScriptErrorsSuppressed is set to false.
    browser.ScriptErrorsSuppressed = false;

    // Handle DocumentCompleted to gain access to the Document object.
    browser.DocumentCompleted +=
        new WebBrowserDocumentCompletedEventHandler(
            browser_DocumentCompleted);


private void browser_DocumentCompleted(object sender, 
    WebBrowserDocumentCompletedEventArgs e)

    ((WebBrowser)sender).Document.Window.Error += 
        new htmlElementErrorEventHandler(Window_Error);


private void Window_Error(object sender, 
    HtmlElementErrorEventArgs e)

    // Ignore the error and suppress the error dialog box. 
    e.Handled = true;

【讨论】:

这应该有更多的赞成票,绝对是正确的做法。能够记录错误或显示您自己的通知而不是永远不知道它们曾经发生过的奖励(即对于信息亭应用程序)。 在我的测试中,我发现在触发 DocumentCompleted 事件之前会出现脚本错误对话框。但是,如果 WebBrowser.Document.Window.Error 处理程序作为对 Navigated 和 FileDownloaded 事件的响应而附加,则可以抑制大多数(如果不是全部)脚本错误对话框。 (FileDownloaded 处理大多数情况,除了 WebBrowser.GoBack,它由 Navigated 处理。单独 Navigated 会错过刷新的页面。) @Ej。很好,我遇到了并非所有 JavaScript 错误都被捕获的问题,这可能会解决问题,您能否有一个示例说明您是如何实现它的? 这是我使用的:pastebin.com/UThKifw8 虽然,我们还必须让用户在对话框完全消失之前升级到 IE8。 仅供参考,我无法使用此解决方案,因为 HTML 页面包含框架集和框架,这导致跨框架安全检查引发异常(请参阅 WebBrowser.Document property getter throws UnauthorizedAccessException)【参考方案3】:

上述解决方案都不适合我的场景,处理 .Navigated 和 .FileDownload 事件似乎很合适,但访问 WebBrowser.Document 属性会引发 UnauthorizedAccessException,这是由跨框架脚本安全性引起的(我们的 Web 内容包含框架- 都在同一个域/地址上,但框架有自己的安全漏洞被阻止)。

有效的解决方案是覆盖 IOleCommandTarget 并在该级别捕获脚本错误命令。这是实现此目的的 WebBrowser 子类:

/// <summary>
/// Subclassed WebBrowser that suppresses error pop-ups.
/// 
/// Notes.
/// ScriptErrorsSuppressed property is not used because this actually suppresses *all* pop-ups.
/// 
/// More info at:
/// http://***.com/questions/2476360/disable-javascript-error-in-webbrowser-control
/// </summary>
public class WebBrowserEx : WebBrowser

    #region Constructor

    /// <summary>
    /// Default constructor.
    /// Initialise browser control and attach customer event handlers.
    /// </summary>
    public WebBrowserEx()
    
        this.ScriptErrorsSuppressed = false;
    

    #endregion

    #region Overrides

    /// <summary>
    /// Override to allow custom script error handling.
    /// </summary>
    /// <returns></returns>
    protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
    
        return new WebBrowserSiteEx(this);
    

    #endregion

    #region Inner Class [WebBrowserSiteEx]

    /// <summary>
    /// Sub-class to allow custom script error handling.
    /// </summary>
    protected class WebBrowserSiteEx : WebBrowserSite, NativeMethods.IOleCommandTarget
    
        /// <summary>
        /// Default constructor.
        /// </summary>
        public WebBrowserSiteEx(WebBrowserEx webBrowser) : base (webBrowser)
           
        

        /// <summary>Queries the object for the status of one or more commands generated by user interface events.</summary>
        /// <param name="pguidCmdGroup">The GUID of the command group.</param>
        /// <param name="cCmds">The number of commands in <paramref name="prgCmds" />.</param>
        /// <param name="prgCmds">An array of OLECMD structures that indicate the commands for which the caller needs status information. This method fills the <paramref name="cmdf" /> member of each structure with values taken from the OLECMDF enumeration.</param>
        /// <param name="pCmdText">An OLECMDTEXT structure in which to return name and/or status information of a single command. This parameter can be null to indicate that the caller does not need this information.</param>
        /// <returns>This method returns S_OK on success. Other possible return values include the following.
        /// E_FAIL The operation failed.
        /// E_UNEXPECTED An unexpected error has occurred.
        /// E_POINTER The <paramref name="prgCmds" /> argument is null.
        /// OLECMDERR_E_UNKNOWNGROUP The <paramref name="pguidCmdGroup" /> parameter is not null but does not specify a recognized command group.</returns>
        public int QueryStatus(ref Guid pguidCmdGroup, int cCmds, NativeMethods.OLECMD prgCmds, IntPtr pCmdText)
        
            if((int)NativeMethods.OLECMDID.OLECMDID_SHOWSCRIPTERROR == prgCmds.cmdID)
               // Do nothing (suppress script errors)
                return NativeMethods.S_OK;
            

            // Indicate that command is unknown. The command will then be handled by another IOleCommandTarget.
            return NativeMethods.OLECMDERR_E_UNKNOWNGROUP;
        

        /// <summary>Executes the specified command.</summary>
        /// <param name="pguidCmdGroup">The GUID of the command group.</param>
        /// <param name="nCmdID">The command ID.</param>
        /// <param name="nCmdexecopt">Specifies how the object should execute the command. Possible values are taken from the <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDEXECOPT" /> and <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDID_WINDOWSTATE_FLAG" /> enumerations.</param>
        /// <param name="pvaIn">The input arguments of the command.</param>
        /// <param name="pvaOut">The output arguments of the command.</param>
        /// <returns>This method returns S_OK on success. Other possible return values include 
        /// OLECMDERR_E_UNKNOWNGROUP The <paramref name="pguidCmdGroup" /> parameter is not null but does not specify a recognized command group.
        /// OLECMDERR_E_NOTSUPPORTED The <paramref name="nCmdID" /> parameter is not a valid command in the group identified by <paramref name="pguidCmdGroup" />.
        /// OLECMDERR_E_DISABLED The command identified by <paramref name="nCmdID" /> is currently disabled and cannot be executed.
        /// OLECMDERR_E_NOHELP The caller has asked for help on the command identified by <paramref name="nCmdID" />, but no help is available.
        /// OLECMDERR_E_CANCELED The user canceled the execution of the command.</returns>
        public int Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, object[] pvaIn, int pvaOut)
        
            if((int)NativeMethods.OLECMDID.OLECMDID_SHOWSCRIPTERROR == nCmdID)
               // Do nothing (suppress script errors)
                return NativeMethods.S_OK;
            

            // Indicate that command is unknown. The command will then be handled by another IOleCommandTarget.
            return NativeMethods.OLECMDERR_E_UNKNOWNGROUP;
        
    

    #endregion

~

/// <summary>
/// Native (unmanaged) methods, required for custom command handling for the WebBrowser control.
/// </summary>
public static class NativeMethods

    /// From docobj.h
    public const int OLECMDERR_E_UNKNOWNGROUP = -2147221244;

    /// <summary>
    /// From Microsoft.VisualStudio.OLE.Interop (Visual Studio 2010 SDK).
    /// </summary>
    public enum OLECMDID
    
        /// <summary />
        OLECMDID_OPEN = 1,
        /// <summary />
        OLECMDID_NEW,
        /// <summary />
        OLECMDID_SAVE,
        /// <summary />
        OLECMDID_SAVEAS,
        /// <summary />
        OLECMDID_SAVECOPYAS,
        /// <summary />
        OLECMDID_PRINT,
        /// <summary />
        OLECMDID_PRINTPREVIEW,
        /// <summary />
        OLECMDID_PAGESETUP,
        /// <summary />
        OLECMDID_SPELL,
        /// <summary />
        OLECMDID_PROPERTIES,
        /// <summary />
        OLECMDID_CUT,
        /// <summary />
        OLECMDID_COPY,
        /// <summary />
        OLECMDID_PASTE,
        /// <summary />
        OLECMDID_PASTESPECIAL,
        /// <summary />
        OLECMDID_UNDO,
        /// <summary />
        OLECMDID_REDO,
        /// <summary />
        OLECMDID_SELECTALL,
        /// <summary />
        OLECMDID_CLEARSELECTION,
        /// <summary />
        OLECMDID_ZOOM,
        /// <summary />
        OLECMDID_GETZOOMRANGE,
        /// <summary />
        OLECMDID_UPDATECOMMANDS,
        /// <summary />
        OLECMDID_REFRESH,
        /// <summary />
        OLECMDID_STOP,
        /// <summary />
        OLECMDID_HIDETOOLBARS,
        /// <summary />
        OLECMDID_SETPROGRESSMAX,
        /// <summary />
        OLECMDID_SETPROGRESSPOS,
        /// <summary />
        OLECMDID_SETPROGRESSTEXT,
        /// <summary />
        OLECMDID_SETTITLE,
        /// <summary />
        OLECMDID_SETDOWNLOADSTATE,
        /// <summary />
        OLECMDID_STOPDOWNLOAD,
        /// <summary />
        OLECMDID_ONTOOLBARACTIVATED,
        /// <summary />
        OLECMDID_FIND,
        /// <summary />
        OLECMDID_DELETE,
        /// <summary />
        OLECMDID_HTTPEQUIV,
        /// <summary />
        OLECMDID_HTTPEQUIV_DONE,
        /// <summary />
        OLECMDID_ENABLE_INTERACTION,
        /// <summary />
        OLECMDID_ONUNLOAD,
        /// <summary />
        OLECMDID_PROPERTYBAG2,
        /// <summary />
        OLECMDID_PREREFRESH,
        /// <summary />
        OLECMDID_SHOWSCRIPTERROR,
        /// <summary />
        OLECMDID_SHOWMESSAGE,
        /// <summary />
        OLECMDID_SHOWFIND,
        /// <summary />
        OLECMDID_SHOWPAGESETUP,
        /// <summary />
        OLECMDID_SHOWPRINT,
        /// <summary />
        OLECMDID_CLOSE,
        /// <summary />
        OLECMDID_ALLOWUILESSSAVEAS,
        /// <summary />
        OLECMDID_DONTDOWNLOADCSS,
        /// <summary />
        OLECMDID_UPDATEPAGESTATUS,
        /// <summary />
        OLECMDID_PRINT2,
        /// <summary />
        OLECMDID_PRINTPREVIEW2,
        /// <summary />
        OLECMDID_SETPRINTTEMPLATE,
        /// <summary />
        OLECMDID_GETPRINTTEMPLATE
    

    /// <summary>
    /// From Microsoft.VisualStudio.Shell (Visual Studio 2010 SDK).
    /// </summary>
    public const int S_OK = 0;

    /// <summary>
    /// OLE command structure.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public class OLECMD
    
        /// <summary>
        /// Command ID.
        /// </summary>
        [MarshalAs(UnmanagedType.U4)]
        public int cmdID;
        /// <summary>
        /// Flags associated with cmdID.
        /// </summary>
        [MarshalAs(UnmanagedType.U4)]
        public int cmdf;
    

    /// <summary>
    /// Enables the dispatching of commands between objects and containers.
    /// </summary>
    [ComVisible(true), Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [ComImport]
    public interface IOleCommandTarget
    
        /// <summary>Queries the object for the status of one or more commands generated by user interface events.</summary>
        /// <param name="pguidCmdGroup">The GUID of the command group.</param>
        /// <param name="cCmds">The number of commands in <paramref name="prgCmds" />.</param>
        /// <param name="prgCmds">An array of <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMD" /> structures that indicate the commands for which the caller needs status information.</param>
        /// <param name="pCmdText">An <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDTEXT" /> structure in which to return name and/or status information of a single command. This parameter can be null to indicate that the caller does not need this information.</param>
        /// <returns>This method returns S_OK on success. Other possible return values include the following.
        /// E_FAIL The operation failed.
        /// E_UNEXPECTED An unexpected error has occurred.
        /// E_POINTER The <paramref name="prgCmds" /> argument is null.
        /// OLECMDERR_E_UNKNOWNGROUPThe <paramref name="pguidCmdGroup" /> parameter is not null but does not specify a recognized command group.</returns>
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.I4)]
        int QueryStatus(ref Guid pguidCmdGroup, int cCmds, [In] [Out] NativeMethods.OLECMD prgCmds, [In] [Out] IntPtr pCmdText);

        /// <summary>Executes the specified command.</summary>
        /// <param name="pguidCmdGroup">The GUID of the command group.</param>
        /// <param name="nCmdID">The command ID.</param>
        /// <param name="nCmdexecopt">Specifies how the object should execute the command. Possible values are taken from the <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDEXECOPT" /> and <see cref="T:Microsoft.VisualStudio.OLE.Interop.OLECMDID_WINDOWSTATE_FLAG" /> enumerations.</param>
        /// <param name="pvaIn">The input arguments of the command.</param>
        /// <param name="pvaOut">The output arguments of the command.</param>
        /// <returns>This method returns S_OK on success. Other possible return values include 
        /// OLECMDERR_E_UNKNOWNGROUP The <paramref name="pguidCmdGroup" /> parameter is not null but does not specify a recognized command group.
        /// OLECMDERR_E_NOTSUPPORTED The <paramref name="nCmdID" /> parameter is not a valid command in the group identified by <paramref name="pguidCmdGroup" />.
        /// OLECMDERR_E_DISABLED The command identified by <paramref name="nCmdID" /> is currently disabled and cannot be executed.
        /// OLECMDERR_E_NOHELP The caller has asked for help on the command identified by <paramref name="nCmdID" />, but no help is available.
        /// OLECMDERR_E_CANCELED The user canceled the execution of the command.</returns>
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.I4)]
        int Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, [MarshalAs(UnmanagedType.LPArray)] [In] object[] pvaIn, int pvaOut);
    

【讨论】:

谢谢,谢谢,谢谢。那么目前只有工作解决方案。非常感谢:D。 直到下一个 IE 版本!! 我明白了。该方法支持哪些IE版本? 我正在使用 IE10 和 11,但我主要关心的是 IE 替代品 - Microsoft Edge 会发生什么。 Microsoft Edge 不会发生任何事情,因为 Microsoft 不会让您将 Edge 嵌入 WinForms 应用程序,以试图强迫您为其新的锁定“通用”平台构建应用程序相反 - (在此页面上搜索 embed - dev.windows.com/en-us/microsoft-edge/platform/faq/apps-engine)【参考方案4】:

axwebbrowser1.Silent = true;

【讨论】:

【参考方案5】:

这是一个替代解决方案:

class extendedWebBrowser : WebBrowser

    /// <summary>
    /// Default constructor which will make the browser to ignore all errors
    /// </summary>
    public extendedWebBrowser()
    
        this.ScriptErrorsSuppressed = true;

        FieldInfo field = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
        if (field != null)
        
             object axIWebBrowser2 = field.GetValue(this);
             axIWebBrowser2.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, axIWebBrowser2, new object[]  true );
        
    

【讨论】:

【参考方案6】:

我刚刚发现了这个:

 private static bool TrySetSuppressScriptErrors(WebBrowser webBrowser, bool value)
    
        FieldInfo field = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
        if (field != null)
        
            object axIWebBrowser2 = field.GetValue(webBrowser);
            if (axIWebBrowser2 != null)
            
                axIWebBrowser2.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, axIWebBrowser2, new object[]  value );
                return true;
            
        

        return false;
    

将 webBrowser 设置为静默的使用示例:TrySetSuppressScriptErrors(webBrowser,true)

【讨论】:

以上是关于在 WebBrowser 控件中禁用 JavaScript 错误的主要内容,如果未能解决你的问题,请参考以下文章

在WebBrowser控件中禁用脚本?

如何禁用 .NET WebBrowser 控件中的缓存?

如何在 Webbrowser 控件中禁用“安全警报”窗口

如何禁用 WPF WebBrowser 控件的点击噪音?

WebBrowser禁用触摸缩放

C# webBrowser控件禁用alert,confirm之类的弹窗解决方案