最直接有效的方式是通过 HTTP 响应头 X-Frame-Options 设置为 DENY,浏览器原生支持且不可被 JS 绕过;推荐 Nginx 或 Apache 服务端配置,同时可辅以 CSP frame-ancestors 提升兼容性与灵活性。

如何用 X-Frame-Options 阻止页面被 iframe 嵌入
最直接有效的方式是通过 HTTP 响应头 X-Frame-Options 控制嵌入行为,浏览器原生支持,无需 JS 干预,且优先级高于前端手段。
它有三个可选值:DENY(任何页面都不能嵌入)、SAMEORIGIN(仅同源页面可嵌入)、ALLOW-FROM uri(已废弃,现代浏览器基本不支持)。
- 推荐始终使用
X-Frame-Options: DENY,除非你明确需要同源嵌入 - Nginx 配置示例:
add_header X-Frame-Options "DENY" always; - Apache 配置示例:
Header always set X-Frame-Options "DENY" - 注意:该 Header 不能被前端 JS 覆盖或绕过,但若服务端未配置,仅靠前端代码无法真正阻止嵌入
Content-Security-Policy 的 frame-ancestors 替代方案
X-Frame-Options 已逐渐被更灵活的 Content-Security-Policy 中的 frame-ancestors 指令取代。它支持更细粒度控制,且兼容性在现代浏览器中已足够好(Chrome 39+、Firefox 34+、Edge 12+)。
- 禁止所有嵌入:
Content-Security-Policy: frame-ancestors 'none'; - 只允许同源嵌入:
Content-Security-Policy: frame-ancestors 'self'; - 允许多个指定域名:
Content-Security-Policy: frame-ancestors https://a.example.com https://b.example.com; - 如果同时设置了
X-Frame-Options和frame-ancestors,浏览器会以更严格的策略为准;但部分旧版浏览器(如 IE)只认X-Frame-Options,所以建议两者共存
前端 JS 检测是否被 iframe 嵌入并跳转(辅助手段)
JS 层面只能「检测」和「响应」,不能真正阻止嵌入——页面已被加载,攻击者仍可截获 HTML 或观察网络请求。但它对防止误操作或简单钓鱼有一定提示作用。
立即学习“前端免费学习笔记(深入)”;
常见检测逻辑是比对 window.top 和 window.self:
if (window.top !== window.self) {
window.top.location = window.self.location;
}
- 该代码放在
<head>最顶部执行,减少白屏时间 - 注意:若父页面启用了
sandbox属性(如sandbox="allow-scripts"),可能阻断此脚本运行 - 存在绕过风险:父页面可通过
document.domain修改域(仅限旧版 IE/老式子域场景),或用srcdoc+ 内联 HTML 规避跨域限制 - 不要依赖它做安全边界,仅作用户体验兜底
为什么不能只靠 <meta> 标签设置 CSP frame-ancestors
<meta http-equiv="Content-Security-Policy" content="frame-ancestors 'none';"> 看似方便,但实际无效——frame-ancestors 指令**不支持通过 <meta> 标签声明**,必须由 HTTP 响应头传递。
- 浏览器规范明确要求:
frame-ancestors只在响应头中生效,<meta>中出现会被完全忽略 - 其他 CSP 指令(如
script-src)可用 <meta> 设置,但这是特例,不是通则 - 若误用 <meta>,开发工具 Network 面板中看不到对应策略,也收不到违规报告(即使开启了
report-uri)
真正起效的安全防护必须落在服务端响应头上;前端 JS 是补丁,<meta> 是陷阱。最容易被忽略的是:本地开发时用 file:// 协议打开 HTML,所有这些 HTTP 头策略都不生效——务必在真实 HTTP(S) 服务下测试。


















