X-Frame-Options 设置后为什么页面还是能被嵌入 iframe?

设计师亚捷 阅读 28

我在项目里加了 X-Frame-Options: DENY 响应头,但发现别人还是能用 iframe 把我的 React 页面嵌进去,完全没生效。是我配置错了吗?

后端是用 Nginx 配的 header,前端代码大概是这样:

function App() {
  return (
    <div className="app">
      <h1>我的安全页面</h1>
      <p>不应该被嵌入 iframe</p>
    </div>
  );
}

export default App;

本地测试时用另一个 HTML 文件直接写 iframe src 指向这个页面,居然能正常显示……这不就绕过防护了吗?

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
A. 小青
A. 小青 Lv1
这问题我也踩过坑,多半是Nginx配置没生效。先确认下你的X-Frame-Options确实返回了,用curl测试下:

curl -I http://你的域名


如果没看到这个header,说明Nginx没配对。正确配置应该是这样(别用add_header,容易踩坑):

server {
location / {
proxy_pass http://你的react应用;
proxy_hide_header X-Frame-Options; # 先清除可能存在的旧header
add_header X-Frame-Options "DENY" always; # 关键在always
}
}


如果还是不行,可能是被其他中间件覆盖了。还有个更现代的方案,直接用Content-Security-Policy:

add_header Content-Security-Policy "frame-ancestors 'none'" always;


两个方案选一个就行,CSP更强大些。配完记得reload nginx服务。
点赞
2026-03-06 11:08
小胜捷
小胜捷 Lv1
这种情况十有八九是你本地开发环境直接跑的是 React 自带的 dev server(比如 npm start),请求根本没走 Nginx。Nginx 配得再花哨,请求没过它,header 自然也就加不上。别光看配置文件,先用浏览器控制台 Network 面板抓个包,看看响应头里到底有没有 X-Frame-Options 这玩意儿。如果没有,那就是配置没生效或者请求路径不对。

如果确定是走 Nginx 代理,配置语法得注意别写错位置。要在 server 块或者具体的 location 块里加,而且建议加上 always 参数,这样即使 Nginx 返回 4xx 或 5xx 错误,安全头也会带上,防止被钻空子。

给你个标准的 Nginx 配置参考,通常是这么写的:

server {
listen 80;
server_name yourdomain.com;

location / {
proxy_pass http://localhost:3000; # 假设你的 React 前端跑在 3000 端口
# 添加响应头,防止被嵌入 iframe
add_header X-Frame-Options "DENY" always;
}
}


另外,X-Frame-Options 已经算是比较老的防御手段了,虽然现在浏览器还支持,但为了防止注入攻击以及应对未来可能的废弃,更推荐用 CSP (Content Security Policy) 的 frame-ancestors 指令。它能更细粒度地控制谁可以嵌套你的页面。建议把 CSP 也加上,做个双重保险。

配置改完记得执行 nginx -s reload 重载配置,并且一定要硬刷新浏览器(Ctrl+F5)把缓存清干净。安全配置这东西,宁可信其无,不可信其有,一定要自己抓包验证响应头确实存在了才行。
点赞
2026-03-04 05:00