Framebuster 防点击劫持为啥在某些浏览器里失效了?

萌新.炜曦 阅读 14

我最近在项目里加了个 Framebuster 代码防止页面被嵌套,但测试发现 Safari 和部分 Chrome 版本里还是能被 iframe 嵌入,根本拦不住。是我写法有问题吗?

我用的这段 JS 是网上常见的方案:

if (window.top !== window.self) {
  window.top.location = window.self.location;
}

本地 dev 环境试了没问题,但部署到线上后,别人用 iframe 引用我的页面居然还能正常显示,完全没跳转。这到底咋回事?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
闲人珍珍
你这段代码本身没问题,但问题出在它只在页面加载后执行,而现代浏览器的 iframe 防嵌套策略已经变了——特别是 Safari 和新版 Chrome,会先渲染 iframe 内容再执行 JS,导致你这段代码还没来得及跳转,页面就已经被嵌进去了。

更稳妥的做法是配合 HTTP 响应头用,别光靠 JS。直接用两个响应头:

X-Frame-Options: DENY
或者
X-Frame-Options: SAMEORIGIN

如果后端是 Node、Java、PHP 之类的,加起来很简单,比如 Node 的 Express 用 helmet 中间件:

const helmet = require('helmet');
app.use(helmet.frameguard({ action: 'deny' }));


或者 Nginx 里加:

add_header X-Frame-Options "DENY";


如果后端改不动,或者想双保险,把你的 JS 也改成更激进的写法——直接放在 head 里,用内联 script,避免被其他 JS 打断:

<head>
<script>
if (window.top !== window.self) {
try {
window.top.location.href = window.location.href;
} catch (e) {
document.body.innerHTML = '';
}
}
</script>
</head>


注意 try-catch 是为了防跨域报错,Safari 在某些沙箱模式下会直接 throw,这时候清空 body 也能阻断展示。

最后提醒一句:Safari 对 iframe 的 sandbox 属性和 cookie 限制特别严格,如果被嵌页面用了第三方 Cookie(比如登录态),Safari 默认可能直接拦截,导致你测的时候以为“能嵌进去”,其实只是 iframe 内部白屏了,这种情况不是 framebuster 失效,是浏览器策略生效了。
点赞 2
2026-02-26 20:29