如何防止Flutter Web应用被嵌入iframe并检测嵌入域名?
阻止Flutter Web应用被iframe嵌入及检测宿主域名的方法
问题描述
我在Firebase上创建项目并托管了Flutter Web应用:https://friendlyeats-flutter-codelab.firebaseapp.com/#/。发现该应用可被任意网站通过iframe嵌入显示,请问是否有办法阻止这种情况?
我尝试使用Uri.base.host、Uri.base.origin、Uri.base.authority等属性检测嵌入宿主域名,但即使在其他域名(如some-website.com)的iframe中嵌入,这些值仍显示为friendlyeats-flutter-codelab.firebaseapp.com。请问是否有办法通过Dart/Flutter检测iframe的宿主域名?
补充:我还尝试了以下代码,结果依旧:
html.window?.location?.host html.window?.location?.href html.window?.location?.origin html.window?.origin html.window?.document?.origin //null html.window?.document?.domain html.window?.document?.baseUri html.window?.document?.suborigin //null html.window?.document?.window?.location html.window?.document?.parent?.namespaceUri //null
解决方案
1. 最可靠的方式:通过Firebase Hosting设置CSP阻止iframe嵌入
从服务器层面限制允许嵌入应用的域名,这是安全且有效的核心方案,不受客户端代码限制。
在Firebase项目的firebase.json文件中,修改hosting配置,添加headers设置Content-Security-Policy的frame-ancestors指令:
{ "hosting": { "public": "build/web", "headers": [ { "source": "**", "headers": [ { "key": "Content-Security-Policy", "value": "frame-ancestors 'self'; " } ] } ] } }
'self'表示仅允许自身域名嵌入;- 如需允许特定域名,例如
https://example.com,可修改为frame-ancestors 'self' https://example.com;; - 若要完全禁止所有iframe嵌入,设置为
frame-ancestors 'none';。
修改完成后重新部署:firebase deploy --only hosting即可生效。
2. Dart/Flutter客户端检测iframe环境(存在局限性)
受浏览器同源策略限制,若嵌入应用的是不同域名的网站,你无法直接获取宿主域名(会触发跨域错误),但可以检测当前应用是否处于iframe中:
import 'dart:html' as html; void checkIframeEnvironment() { bool isInIframe = html.window.self != html.window.top; if (isInIframe) { // 处理iframe环境,比如跳转到顶层窗口 html.window.top?.location?.replace(html.window.location.href); // 或显示提示信息 print('当前应用被嵌入到iframe中'); } }
- 此方法仅能检测是否处于iframe环境,无法获取非同源的宿主域名;
- 若宿主域名与应用同源,可尝试通过
html.window.parent.location.host获取,但该场景较为少见。
内容的提问来源于stack exchange,提问作者RedDeath
相关产品推荐
相关产品推荐

