在Delphi TWebbrowser控件中禁止“你确定要保留此页面”弹出窗口

时间:2013-10-13 18:16:48

标签: delphi webbrowser-control twebbrowser

我有一个Delphi应用程序,它使用TWebbrowser组件自动导航到我们拥有的另一个Web应用程序。

我的问题是,有时IE会显示臭名昭着的“您确定要离开此页面”消息,当发生这种情况时,我的应用无法导航到其他页面,除非用户点击“离开此页面”按钮。不幸的是,我无法编辑网站代码来删除此警告。

此消息困扰我的应用数周,我无法再找到合适的解决方案了。我做的是保持后台进程在显示此窗口时手动发送击键,但这不是一个好的解决方案,因为在我的应用程序运行时没有人可以使用计算机。

我在下面的主题中看到了C#的可能解决方案,但我需要一个Delphi代码。

Supress the "are you sure you want to leave this page" popup in the .NET webbrowser control

非常非常感谢任何帮助。

谢谢:)

3 个答案:

答案 0 :(得分:3)

如果网页处理window.onbeforeunload事件,则底层MSHTML引擎会显示此消息。通常,出于某种原因,让用户知道他/她的输入尚未保存或提交。来自the answer you linked的提示抑制脚本不适用于页面使用addEventListener("beforeonload", handler)attachEvent("onbeforeunload", handler)的情况。我不认为这是一种可行的方法,而不需要使用低级别的Windows挂钩。

[更新] 以下脚本(查找"注入此脚本")是一个黑客攻击,它会主动抑制页面自己的onbeforeunload处理程序活动,通过setInterval。它应该在99%的情况下有效,但在导航之前页面仍然会覆盖onbeforeonload

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title></title>
    <script type="text/javascript">
        window.attachEvent("onbeforeunload", function (ev) {
            window.event.returnValue = "onbeforeunload via window.attachEvent()";
        });

        window.addEventListener("beforeunload", function (ev) {
            window.event.returnValue = "onbeforeunload via window.addEventListener()";
        });

        window.onbeforeunload = function (ev) {
            window.event.returnValue = "onbeforeunload via window.onbeforeunload";
        };
    </script>

    <script type="text/javascript">
        //
        // Inject this script
        //
        (function () {
            var onbeforeunloadHandler = function (ev) {
                if (ev) {
                    if (ev.stopPropagation)
                        ev.stopPropagation();
                    if (ev.stopImmediatePropagation)
                        ev.stopImmediatePropagation();
                    ev.returnValue = undefined;
                }
                window.event.returnValue = undefined;
            }

            var handler = null;
            var intervalHandler = function () {
                if (handler)
                    window.detachEvent("onbeforeunload", handler);

                // window.attachEvent works best
                handler = window.attachEvent("onbeforeunload", onbeforeunloadHandler);
                // handler = window.addEventListener("beforeunload", onbeforeunloadHandler);
                // handler = window.onload = onbeforeunloadHandler;
            };

            window.setInterval(intervalHandler, 500);
            intervalHandler();
        })();
    </script>

</head>
<body>
    <a href="http://www.example.com">Go away</a>
</body>
</html>

要使用Delphi注入此脚本,您可能需要使用低级WebBrowser/MSHTML COM接口,例如IWebBrowser2IHTMLDocument2IHTMLScriptElement,以一种非常类似的方式在链接的答案中完成。通过后期绑定,只需使用IDispatch::GetIDsOfNamesIDispatch::Invoke,也可以进行更多努力。如果你要求确切的德尔福代码,我就没有。

答案 1 :(得分:1)

您链接的其他答案处理浏览器的Navigated事件。在其中,它将脚本元素注入页面并进入页面上的每个框架。该脚本为window.alert分配了一个新值,以便当页面上的其他代码调用它时,它什么都不做。

答案 2 :(得分:1)

此代码重置事件处理程序:

var
  WrkIHTMLWindow2: IHTMLWindow2;
  WrkIHTMLWindow2Disp: IHTMLWindow2Disp;
begin
  WrkIHTMLWindow2 := IHTMLDocument2Disp(WrkIWebBrowser2.Document).parentWindow;
  if WrkIHTMLWindow2.QueryInterface(IHTMLWindow2Disp, WrkIHTMLWindow2Disp) = S_OK then
    if not VarIsNull(WrkIHTMLWindow2Disp.onbeforeunload) then
      WrkIHTMLWindow2Disp.onbeforeunload := NULL;
end;