Greasemonkey-issued 重定向仅在重定向行之后调用 alert() 时有效
Greasemonkey-issued redirect only works if alert() is called after the redirection line
我工作的一个网站在未登录时会重定向到错误的登录页面。
<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:
header。
为了解决这个问题,我编写了一个 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()
是 时,我从来没有看到警告框,但是 do 被重定向到正确的页面。
我可以保留 alert()
,因为它似乎从来没有 运行,但我想删除它并仍然让页面重定向到我想要的页面。
我对这个问题的疑问:
- 为什么会出现这种情况?是否涉及时间问题?
- 如何在没有无用的
alert()
调用的情况下使它正常工作?
该代码有一些 "race conditions"。由于缺少 alert()
,旧的 JS 仍会在 location.replace();
完成之前触发。
警报需要时间才能触发。有了它,location.replace
就可以提前完成。
正确的做法是停止脚本,然后启动替换。使用 stopPropagation
和 preventDefault
执行此操作。像这样:
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);
我工作的一个网站在未登录时会重定向到错误的登录页面。
<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:
header。
为了解决这个问题,我编写了一个 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()
是 时,我从来没有看到警告框,但是 do 被重定向到正确的页面。
我可以保留 alert()
,因为它似乎从来没有 运行,但我想删除它并仍然让页面重定向到我想要的页面。
我对这个问题的疑问:
- 为什么会出现这种情况?是否涉及时间问题?
- 如何在没有无用的
alert()
调用的情况下使它正常工作?
该代码有一些 "race conditions"。由于缺少 alert()
,旧的 JS 仍会在 location.replace();
完成之前触发。
警报需要时间才能触发。有了它,location.replace
就可以提前完成。
正确的做法是停止脚本,然后启动替换。使用 stopPropagation
和 preventDefault
执行此操作。像这样:
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);