React 项目如何防止被嵌入 iframe 导致点击劫持?

IT人爱静 阅读 56

我最近在做公司后台系统,用的是 React,担心被人用 iframe 嵌套我们的页面搞点击劫持。听说可以通过设置 X-Frame-Options 或 Content-Security-Policy 来防护,但我在前端代码里加了好像没生效?

我在 App.js 里尝试用 useEffect 加了个 meta 标签,但控制台报错说无效,而且页面还是能被别人用 iframe 嵌入。是不是这种防护只能在后端设置?前端能做点啥吗?

useEffect(() => {
  const meta = document.createElement('meta');
  meta.httpEquiv = 'Content-Security-Policy';
  meta.content = "frame-ancestors 'self'";
  document.head.appendChild(meta);
  return () => document.head.removeChild(meta);
}, []);
我来解答 赞 10 收藏
二维码
手机扫码查看
2 条解答
思涵
思涵 Lv1
你这个问题挺常见的,很多人以为前端能搞定,其实没那么简单。

先说为什么你的代码不生效:X-Frame-Options 和 Content-Security-Policy 这些都是 HTTP 响应头,是在服务器返回响应时就决定好的。浏览器收到响应后才会解析 meta 标签,但 CSP 的 frame-ancestors 这类指令根本不支持通过 meta 标签设置,浏览器直接忽略。所以你动态添加 meta 标签完全是白忙活。

真正的解决办法还是在后端。服务端配置就几种方式:

Nginx 的话在 server 块加 add_header X-Frame-Options "SAMEORIGIN";,或者用 CSP 的话 add_header Content-Security-Policy "frame-ancestors 'self'";。Apache 用 .htaccess 设置 Header set X-Frame-Options "SAMEORIGOR"。如果你用云服务比如阿里云 CDN,也可以在 CDN 配置里加这些响应头。

如果你实在控制不了后端,前端倒是能做个检测然后强行跳转,代码大概这样:

useEffect(() => {
if (window.self !== window.top) {
top.location.href = window.location.href;
}
}, []);


不过这种方式只能防止普通用户点击劫持,稍微懂点技术的直接就能禁掉你的 JS 绕过这个检测。所以后端配置才是靠谱的方案,前端这个也就是个辅助手段。

你们公司后端是 nginx 的话让运维加一行配置就完事了,比在前端折腾省事多了。
点赞
2026-03-14 10:10
百里怡然
你这段代码没生效是正常的,因为这俩都是 HTTP 响应头,不是通过 meta 标签能设置的。浏览器在解析页面之前就已经处理这些头了,你动态挂载 meta 标签根本来不及。

我之前踩过这个坑,后来搞清楚了:

后端设置是必须的。X-Frame-Options 和 CSP 的 frame-ancestors 都得在服务器响应时加上响应头,前端改不了。所以你们后端配置 nginx 或者后端代码里一定要加:

nginx 的话:
add_header X-Frame-Options "SAMEORIGIN";
add_header Content-Security-Policy "frame-ancestors 'self'";

后端语言的话也都有对应的方式设置响应头。

前端能做的事:虽然不能彻底解决,但可以加个检测脚本,被嵌入时给用户提个醒,或者直接跳转到顶级窗口。我之前项目里这么干的:

useEffect(() => {
if (window.self !== window.top) {
// 被嵌入了,可以选择提示或者强制跳出来
window.top.location = window.self.location;
// 或者只显示警告
document.body.innerHTML = '
请勿将本系统嵌入其他网站
';
}
}, []);


不过得说句实话,这种前端方案防君子防不住小人,技术流可以直接把这个检测代码给你干失效。真正的防护还是得靠后端设置响应头,前端这个算是个双保险和用户体验层面的保护。
点赞
2026-03-13 20:01