由于除了沙盒之外无法阻止iframe重定向顶部框架,这会阻止可见度跟踪所需的其他功能,我想跟踪重定向。由于一个站点可以有多个iframe,因此可以是其中任何一个。
有没有办法跟踪/找出哪一个(特定iframe)导致顶部框架重定向?
这是一个沙箱(使用浏览器控制台并启用保留日志):
注意 iframe内容通常是跨域的。为方便使用,它在sandox中。
答案 0 :(得分:5)
我们可以使用iframe.contentWindow.document
之类的东西来访问iframe内容,但是如果我们观察到Same-origin policy,则可以这样做。
另一种方法可能是设置Content-Security-Policy
标头,例如:
<meta http-equiv="Content-Security-Policy" content="frame-src http://example.com">
父页面中的此标头可以阻止在框架中加载与http://example.com不同的网站,还有一种方法可以report进行拒绝行为,以发送帖子,但不幸的是无法使用{{ 1}}标记(仅服务器端)。使用这种方法,我们必须执行白名单,所以我认为在这种情况下可能没有用。但是,如果是第一次提供白名单,则可以设置所有可用站点,因此当iframe重定向时,浏览器将拒绝加载它。
如果不是相同来源的情况以及执行白名单的可能性,那么我认为我们可以做的更好的是调用iframe onunload
事件,不幸的是,在iframe时也会触发此事件页面不仅在重定向时重新加载。我认为这是最接近的方法。为此,此代码有效。
<meta>
当然,var srcs = ["iframe2.html","iframe.html","iframe2.html"];
for (let i = 0; i < srcs.length; i++) {
var iframe = document.createElement('iframe');
iframe.src = srcs[i];
iframe.name = "i"+i;
document.body.appendChild(iframe);
window["i"+i].onunload = function(){console.log("change "+i)}
}
会在所有iframe加载时首次触发,因此重定向是第2 3 3,依此类推。但是我们可以排除第一种情况。
这里有一个完整的示例https://codesandbox.io/s/o16yk7mqy,我创建了iframe3.html,它不会刷新也不会重新加载以清楚地表明要点。另外,我还创建了一个简单的重定向或重新加载iframe列表。
更新
据我所知,您想要的是设置具有sandbox属性的iframe,并将所有您想要的东西都白名单,但没有onunload
,例如:
allow-top-navigation
<iframe src="iframe.html" sandbox="allow-script allow-forms allow-popups allow-pointer-lock allow-same-origin"></iframe>
https://codesandbox.io/s/lpmv6wr6y9 allow-top-navigation
,但 codesandbox 阻止框架重定向,因此,如果我们尝试https://4x8v1mojq7.codesandbox.io/,这是 codesandbox创建的网址,我们可以看到顶部框架重新加载。正如我在评论中所说,至少在Chrome 64.0.3282.167中,当我们在iframe尝试重定向顶部框架时委派了所有操作(但允许顶部导航除外)时,它会抛出异常。 Firefox中的行为有所不同(至少58.0.2)。 Firefox拒绝顶部导航,但继续执行代码。
因此,作为结论,我认为最好的方法是将sanbox与onunload或仅将onunload结合使用。当然,如果可能的话,内容安全策略是最安全,更灵活的方法。这取决于实现方式。我认为几乎不让服务器端代码来执行完美的解决方案几乎是不可能的。有白名单需要检查,例如此API https://developers.google.com/safe-browsing/v4/,还有黑名单需要检查,请看这篇帖子https://security.stackexchange.com/questions/32058/looking-for-url-blacklists-of-malicious-websites。
答案 1 :(得分:-1)
如果您可以控制所有框架,则可以使用postMessage实现框架之间的互动。流速:
父:
window.addEventListener("message", (event) => {
// show message source (your frame)
console.log(event.source);
const message = event.data;
console.log(`Frame ID: ${message.frameId}`);
if(message.messageType === "redirect") {
window.location.href = message.redirectUrl;
}
});
子框架:
function redirect(url) {
var message = {
messageType: "redirect",
frameId: "frame1"
redirectUrl: url
}
window.parent.postMessage(message, "*");
}
答案 2 :(得分:-1)
您可以在重定向到另一个域/应用程序之前显示一个对话框,然后用户可以决定 - 保留或离开当前应用程序。您还可以跟踪当前目标(即您的情况下的iframe)。
window.onbeforeunload = function (e) {
console.log(e.currentTarget.location.href);
return 'Stop redirection. Show dialog box.';
};
答案 3 :(得分:-1)
在各个iframe中,重定向发生时能否设置cookie?假设它发生在iframe1中,您可以设置
这样的cookiedocument.trackFrame = "FrameName=iframe1";
重定向完成后,您可以尝试读取cookie并确定哪个iframe导致了重定向吗?