X-Frame-Options 设置后为什么页面还是能被嵌入 iframe? 一红爱 提问于 2026-02-26 12:56:19 阅读 40 安全 我在项目里加了 X-Frame-Options: DENY 响应头,但本地开发时用 iframe 引入自己的页面居然还能加载出来,是不是我配错了? 后端是用 Express 写的,代码大概是这样: app.use((req, res, next) => { res.setHeader('X-Frame-Options', 'DENY'); next(); }); 浏览器控制台也没报错,但 iframe 里内容正常显示,这不科学啊…… 安全头配置 我来解答 赞 19 收藏 分享 生成中... 手机扫码查看 复制链接 生成海报 反馈 发表解答 您需要先 登录/注册 才能发表解答 2 条解答 圣贤的笔记 Lv1 这个问题其实挺常见的,十有八九是浏览器缓存搞的鬼。 你想想看,你最开始可能没加这个 header 的时候已经访问过页面了,浏览器把响应缓存下来了。后来加了中间件,但浏览器直接从缓存里拿旧响应,根本没发请求到你后端,所以 header 当然没生效。 先试一下:打开浏览器的无痕模式或者彻底清除缓存,再试一次 iframe,如果这时候不能加载了,那就确认是缓存问题。 如果不是缓存,那很可能是中间件顺序的问题。你检查一下代码里静态文件中间件的位置: // 错误的顺序:静态文件直接返回,不经过你的 header 中间件 app.use(express.static('public')); // 这货直接返回文件,跳过了后面的中间件 app.use((req, res, next) => { res.setHeader('X-Frame-Options', 'DENY'); next(); }); // 正确的顺序 app.use((req, res, next) => { res.setHeader('X-Frame-Options', 'DENY'); next(); }); app.use(express.static('public')); Express 的中间件是按顺序执行的,如果静态文件中间件已经返回了响应,代码根本不会走到你设置 header 的地方。 还有一个可能的坑:如果你的页面是通过 file:// 协议打开的,或者 iframe 里的 src 是本地文件路径,某些浏览器对这种情况的 X-Frame-Options 处理不太一致。 你先把缓存清了,然后把中间件顺序调换一下试试,基本就能搞定。 回复 点赞 2026-03-11 19:07 书生シ爱娜 Lv1 你本地开发用的可能是 localhost 或 127.0.0.1,现代浏览器对同源 iframe 嵌套有宽松策略,不会严格拦截 X-Frame-Options。 换成真实域名(比如改 hosts 指向 127.0.0.1)再测,或者加 res.setHeader('Content-Security-Policy', 'frame-ancestors 'none''),后者更可靠。 搞定。 回复 点赞 3 2026-02-26 13:00 加载更多 相关推荐
你想想看,你最开始可能没加这个 header 的时候已经访问过页面了,浏览器把响应缓存下来了。后来加了中间件,但浏览器直接从缓存里拿旧响应,根本没发请求到你后端,所以 header 当然没生效。
先试一下:打开浏览器的无痕模式或者彻底清除缓存,再试一次 iframe,如果这时候不能加载了,那就确认是缓存问题。
如果不是缓存,那很可能是中间件顺序的问题。你检查一下代码里静态文件中间件的位置:
Express 的中间件是按顺序执行的,如果静态文件中间件已经返回了响应,代码根本不会走到你设置 header 的地方。
还有一个可能的坑:如果你的页面是通过 file:// 协议打开的,或者 iframe 里的 src 是本地文件路径,某些浏览器对这种情况的 X-Frame-Options 处理不太一致。
你先把缓存清了,然后把中间件顺序调换一下试试,基本就能搞定。
换成真实域名(比如改 hosts 指向 127.0.0.1)再测,或者加
res.setHeader('Content-Security-Policy', 'frame-ancestors 'none''),后者更可靠。搞定。