只有在重定向行之后调用alert()时,greasemmonkey发出的重定向才有效

Greasemonkey-issued redirect only works if alert() is called after the redirection line

本文关键字:重定向 greasemmonkey 有效 之后 调用 alert      更新时间:2023-09-26

我有一个网站在工作时,没有登录,重定向到错误的登录页面。

<html>
  <head>
    <meta name="robots" content="noindex,nofollow">
    <script type="application/javascript">
      window.location.href = '/access/login?return_to=' + encodeURIComponent(window.location.href);
    </script>
  </head>
</html>

实际页面加载200 OK,没有Location:标头。

为了解决这个问题,我编写了一个Greasemonkey脚本,在页面加载之前运行:

// ==UserScript==
// @name        Fix buggy login redirect
// @namespace  apburk@example.com
// @description Fixes the buggy redirect that redirects to the wrong login page
// @include    https://internal.domain/*
// @version    1
// @grant      none
// @run-at document-start
// ==/UserScript==
window.addEventListener('beforescriptexecute', function(e) {
if (document.getElementsByTagName("script")[0].text.trim() === "window.location.href = '/access/login?return_to=' + encodeURIComponent(window.location.href);") {
window.location.replace('https://example.com');
alert(" ");
}
}, true);

我的脚本检查JavaScript是否重定向到错误的页面,然后将我发送到正确的登录URL。

如果alert()在那里,这个脚本可以正常工作。删除alert()和页面重定向到破碎的登录页面。然而,当alert() 在那里,我从来没有看到警告框,但重定向到适当的页面。

我可以离开alert(),因为它似乎从来没有运行,但我想删除它,仍然有页面重定向到我想要的页面。

关于这个问题我的问题:

  • 为什么会发生这种情况?是否涉及时间问题?
  • 我怎样才能使这个工作正常没有一个无用的alert()调用?

这段代码有一些"竞争条件"。由于alert()缺失,旧的JS仍然在location.replace();完成之前触发。
警报需要一段时间才能发出。有了它,location.replace在它可以完成之前完成。

正确的做法是停止脚本,然后触发替换。这样做与stopPropagationpreventDefault。像这样:

window.addEventListener ('beforescriptexecute', function (e) {
    if (document.getElementsByTagName ("script")[0].text.trim()
        === "window.location.href = '/access/login?return_to=' + encodeURIComponent(window.location.href);"
    ) {
        e.stopPropagation ();
        e.preventDefault ();
        window.location.replace ('https://example.com');
    }
}, true);