x-frame-options比frame-busting javascript更可靠,因其由浏览器在渲染前强制校验,原生支持、不可禁用或绕过;而js可被禁用、sandbox iframe隔离或document.domain降域突破。

为什么 X-Frame-Options 比 frame-busting JavaScript 更可靠
直接用服务端响应头控制比前端脚本更安全——JavaScript 可被禁用、绕过或延迟执行,而 X-Frame-Options 由浏览器在加载前强制校验。主流浏览器(Chrome、Firefox、Safari)均原生支持,且无需依赖 DOM 就生效。
常见错误是只写 JS 防嵌套(比如 if (top !== self) { top.location = self.location; }),但攻击者可通过 sandbox iframe 或 CSP 配置绕过,甚至利用 document.domain 降域突破。服务端头才是第一道防线。
X-Frame-Options 的三种取值及适用场景
该响应头只有三个合法值,不能拼写错误或加空格:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
-
DENY:任何页面都不能被嵌入,最严格,适合登录页、后台管理页 -
SAMEORIGIN:只允许同源的父页面嵌入,适合内部子系统间集成(如app.example.com嵌入api.example.com的仪表盘) -
ALLOW-FROM https://trusted-site.com:仅允许指定来源嵌入(注意:Chrome 从 95 版起已弃用此值,Firefox 也标记为废弃,不建议新项目使用)
如何在不同服务器上设置 X-Frame-Options
必须确保响应头真实发出,可用浏览器开发者工具的 Network → Response Headers 验证是否含 X-Frame-Options: DENY。常见配置方式:
- Apache:在
.htaccess或虚拟主机配置中加Header always set X-Frame-Options "DENY" - Nginx:在 server 或 location 块中加
add_header X-Frame-Options "DENY" always;(always参数关键,否则对 304/错误响应不生效) - Node.js(Express):
app.use((req, res, next) => { res.setHeader('X-Frame-Options', 'DENY'); next(); }); - Python(Flask):
@app.after_request def deny_frame(response): response.headers['X-Frame-Options'] = 'DENY'; return response
当 X-Frame-Options 不够用时,改用 Content-Security-Policy
X-Frame-Options 已被现代标准视为遗留方案,CSP 的 frame-ancestors 指令功能更强、更灵活,且支持多源白名单和通配符:
- 等效
DENY:Content-Security-Policy: frame-ancestors 'none' - 等效
SAMEORIGIN:Content-Security-Policy: frame-ancestors 'self' - 允许多个可信域名:
frame-ancestors 'self' https://partner-a.com https://partner-b.net - 注意:CSP 是覆盖式策略,若同时设置
X-Frame-Options和frame-ancestors,浏览器优先遵循 CSP(Chrome/Firefox 行为一致)
真正容易被忽略的是:CSP 必须通过 HTTP 响应头发送,<meta> 标签不支持 frame-ancestors(会直接被忽略),这点和其它 CSP 指令不同。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










