【问题标题】:How to completely disable all exit warning/confirm messages with userscript?如何使用用户脚本完全禁用所有退出警告/确认消息?
【发布时间】:2015-10-05 21:59:19
【问题描述】:

我在隔离环境中使用 chrome 扫描恶意网站以分析其数据以创建黑名单。这个过程完全由用户脚本和浏览器扩展自动完成。

问题是某些网站能够在beforeunloadunload 上显示退出对话框(我将它们称为events)。

我已经覆盖了这些events,但是当站点再次覆盖我的覆盖时,整个过程就会停止。我的意思是他们可以使用 AJAX 调用、混淆脚本、eval 等重新定义 events

有没有办法摆脱这些消息,或保护我的覆盖? 也许 unsafeWindow 会处理这个问题,但我会避免在这个讨厌的环境中使用它。

编辑 - 目前我在我的用户脚本中使用此代码:

location.href = "javascript:(" + function() {
    window.onbeforeunload = null;
    window.onunload = null;
} + ")()";

setInterval(function(){
    location.href = "javascript:(" + function() {
        window.onbeforeunload = null;
        window.onunload = null;
    } + ")()";
}, 3000);

【问题讨论】:

  • 1.添加您现在使用的代码以阻止这些事件进入问题。 2.基本上我认为你需要使用每一个可以想象的技巧,例如覆盖unsafeWindow中的事件,在定义jQuery时处理unsafeWindow.jQuery._data(unsafeWindow.window, "events")
  • 一段时间内的覆盖(true){} 几乎适用于任何情况,但我不想使用太多资源。
  • 我认为 location hack 在现代浏览器中不起作用,或者在新版本结束测试后几个月内将停止工作。

标签: javascript jquery google-chrome userscripts tampermonkey


【解决方案1】:

我假设您使用的是旧版 Chrome,因为自 Chrome 51 [Custom messages in onbeforeunload dialogs (removed)] 以来,此行为已被删除。

问题依赖于onBeforeUnload 事件。浏览器(Chrome 和 Firefox 至少)已禁用来自 onUnload 事件的消息。您尝试挂接您的计时器并更改window.onbeforeunload = null 的页面可能也在使用计时器以非常小的间隔值设置相同的事件,即使是 1 毫秒,所以当有另一个具有较小间隔的计时器一次又一次地设置它。我的方法是杀死脚本中的所有计时器,它适用于我在旧 VM 中使用的 Chrome 49。

// ==/UserScript==

(function() {
    'use strict';

    var killId = setTimeout(function() {
        for(var i = killId; i > 0; i--) clearInterval(i);
        window.onbeforeunload = null;
        // If you don't use interval timers then disable setInterval function
        // else you can store the function to a variable before
        // you set it to an empty function;
        // Same goes for setTimeout
        setInterval = function() {};
    }, 10);

})();

对于一个参考测试页面,我使用了这个简单的 javascript,它运行一个间隔计时器来设置 window.onbeforeunload 每毫秒:

function goodbye(e) {
    var msg = 'You sure you want to leave?';
    if(!e) e = window.event;
    if(e) {
        //e.cancelBubble is supported by IE - this will kill the bubbling process.
        e.cancelBubble = true;
        e.returnValue = msg; //This is displayed on the dialog

        //e.stopPropagation works in Firefox.
        if (e.stopPropagation) {
            e.stopPropagation();
            e.preventDefault();
        }
    } else
        return msg;
}

// Set a timer to hook `onBeforeUnload` event every millisecond
setInterval(function() { window.onbeforeunload = goodbye; }, 1);

某些页面可能使用setTimeout() 而不是setInterval(),因此您可能还想禁用setTimeout = function() {} 功能。

【讨论】:

  • 这些事件仍在最新的 Chrome 中触发,例如 Windows 上的版本 59.0.3071.115(64 位)。使用它们的网站的一个示例是 Reddit——只需单击回复,输入一些文本,然后关闭窗口或选项卡,您就会看到离开确认弹出窗口。
  • @alzee onBeforeUnload 事件仅在存在表单并且用户填写了一些数据时才会触发。您刚刚在评论中说过;您必须输入一些文本才能出现弹出窗口,否则它不会弹出。如果您只是在没有表单且没有用户填充数据的页面中为其设置侦听器,它将不再触发。您能否提供一个链接,该弹出消息在关闭时由它自己显示没有用户已将一些数据填写到表单中?
  • @alzee 如果脚本仅适用于您并且您需要禁用这些弹出窗口,那么您应该尝试使用选项-disable-prompt-on-repost 启动 Chrome。这将禁用这些消息。我认为您不能通过 javascript 以编程方式禁用它。顺便说一句,这个 Greasemonkey/Tampermonkey 脚本使用的代码是从 2011Greasemonkey/Firefox forums.mozillazine.org/viewtopic.php?p=10347053#p10347053 发布的
  • disable-prompt-on-repost 标志用于不同的东西——防止表单提交在刷新时发生。那面旗帜在这里不会有帮助。这是我希望脚本修复的示例:w3schools.com/Jsref/tryit.asp?filename=tryjsref_onbeforeunload
  • 仅供参考,您引用的链接是一个错误修复,它只会阻止网站在弹出窗口中显示自定义文本,它不会阻止弹出窗口首先显示我和最初的提问者都希望发生这种情况。
【解决方案2】:

试试Object.defineProperty

Object.defineProperty(window, 'onunload', { 
    value: null,
    configurable: false
});

window.onunload = 1;

window.onunload;
// null

configurable 设置为 false,表示该属性无法更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 2012-10-07
    • 1970-01-01
    相关资源
    最近更新 更多