认识
一、认识
如果不考虑体验问题,iframe
几乎是最完美的微前端解决方案了。iframe
最大的特性就是提供了浏览器原生的硬隔离方案,不论是样式隔离、js
隔离这类问题统统都能被完美解决。但他的最大问题也在于他的隔离性无法被突破,导致应用间上下文无法被共享,随之带来的开发体验、产品体验的问题。。Iframe
的特性不仅会导致用户体验下降, 也会在研发中造成较多困扰,比如:
-
使用
Iframe
会大幅度增加内存和计算资源, 因为Iframe
内所承接的页面需要一个全新并且完整的文档环境 -
Iframe
与上层应用并非同一个文档上下文,导致事件冒泡不会穿透到主文档树上,焦点在子应用时,事件无法传递到上一个文档流;主应用劫持快捷键操作;事件无法冒泡到顶层,针对整个应用统一处理失效; -
跳转路径无法与上层文档同步,刷新将丢失路由状态
-
Iframe
内元素会被限制在文档树中,视窗宽高限制问题 -
Iframe
登录状态无法共享,子应用需要重新登录 -
Iframe
在禁用三方Cookie
时,Iframe
平台服务不可用 -
Iframe
应用加载失败,内容发生错误主应用无法感知 -
难以计算出
Iframe
作为页面一部分时的性能情况 -
无法预加载缓存
Iframe
内容 -
无法共享基础库进一步减小包体积
-
事件通信繁琐且限制多
二、语法
三、特点
3.1 脚本隔离(优点)
iframe
提供了浏览器原生的硬隔离方案,不论是样式隔离、 js
隔离这类问题统统都能被完美解决。
3.2 样式隔离(优点)
iframe
提供了浏览器原生的硬隔离方案,不论是样式隔离、 js
隔离这类问题统统都能被完美解决。
3.3 重新加载(缺点)
每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程,占用大量资源的同时也在极大地消耗资源
3.4 Cookie 不共享(缺点)
全局上下文完全隔离,内存变量不共享。iframe
内外系统的通信、数据同步等需求,主应用的 cookie
要透传到根域名都不同的子应用中实现免登效果。
3.5 URL 不同步(缺点)
浏览器刷新 iframe url
状态丢失、后退前进按钮无法使用。
3.6 DOM 结构不共享(缺点)
DOM
结构不共享。想象一下屏幕右下角 1/4
的 iframe
里来一个带遮罩层的弹框,同时我们要求这个弹框要浏览器居中显示,还要浏览器 resize
时自动居中..
四、对比
五、问题
5.1 http 嵌入 https ?
如果页面使用的是 HTTP
协议,而尝试将 HTTPS
页面嵌入到该页面中的 iframe
,浏览器会认为它们不是同源的,从而阻止加载 HTTPS
页面。这是为了保护用户的安全和隐私,防止潜在的安全风险,例如通过 HTTP
页面窃取在 HTTPS
页面中输入的敏感信息。
解决方案:
-
使用
HTTPS
协议: 主页面也迁移到HTTPS
协议,这样就不会涉及到HTTP
和HTTPS
跨域的问题。 -
服务器代理: 在服务器端设置代理,让服务器请求
HTTPS
页面的内容,然后将结果传递给HTTP
页面的前端,由前端进行展示。 -
使用
Subresource Integrity (SRI)
: 如果目标HTTPS
页面提供了SRI
支持,可以使用SRI
来加载和验证脚本和样式。
5.2 iframe cookie 设置共享问题?
iframe cookie
机制: 如果目标网站的登录和会话管理依赖于 Cookie
,由于跨域限制,Cookie
无法在主域中设置或读取,导致登录状态无法正确保存或共
举例来说: 通过 iframe
嵌套了一个 cookie
登录的网站, 但是, 浏览器限制了通过 iframe
中的页面使用 set-cookie
标头来设置 Cookie
。这是出于安全考虑,防止跨域 Cookie
污染攻击。当在 iframe
中加载一个来自不同域的页面时,该页面无法通过设置 set-cookie
标头来在主页面的域中设置 Cookie
。这种限制是由同源策略 (Same-Origin Policy
) 引起的,它要求网页只能访问来自相同域的资源。Cookie
是一种用于跟踪会话状态和存储用户数据的机制,在跨域的情况下,Cookie
可能被恶意网站滥用,因此浏览器禁止了在跨域 。
set-cookie
标头:
-
Strict
: 严格禁止第三方cookie
-
Lax
: 仅对get
请求发送 -
None
:Cookie
只能通过HTTPS
协议发送即必须拥有Secure
字段
解决方案:
-
使用同域代理: 在服务器端设置代理,让服务器请求目标域的资源,然后将结果传递给前端,由前端处理
Cookie
。这样可以避免跨域Cookie
问题。 -
使用
token
: 通过在请求中使用token
来进行身份验证和会话管理,而不依赖于Cookie
。比如我直接嵌入掘金的页面,使用情况是属于正常的 -
CORS
: 可以考虑设置目标网站服务器CORS
响应头,以允许特定域名的请求访问资源。
5.3 iframe 可以嵌入百度首页吗? 为什么?
iframe
嵌入百度首页会出现 Refused to frame 'https://www.baidu.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'
拒绝访问。
遇到的错误消息是由 Content Security Policy
(CSP
) 引起的,CSP
是一种浏览器安全机制,旨在防止恶意攻击,特别是跨站脚本攻击 (XSS
)。这个错误消息表明,在嵌套 www.baidu.com
的页面中,存在一个祖先页面违反了 CSP
指令。这段 CSP
指令的含义是,只有在当前页面的祖先是本身(self
)或指定的一组特定域名下,才允许通过 iframe
嵌入。如果嵌入的页面不满足这些条件,浏览器就会拒绝加载这个 iframe
,并抛出类似于你提供的错误消息。
解决这个问题的方法通常有两种:
-
更新
CSP
指令: 如果你有权限修改当前页面的CSP
指令, 你可以将需要允许的域名添加到frame-ancestors
指令中。在你的例子中,添加你的web
应用域名到CSP
中可能是解决问题的一种方法。Content-Security-Policy: frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com https://fj-chat.baidu.com https://hba-chat.baidu.com https://hbe-chat.baidu.com https://njjs-chat.baidu.com https://nj-chat.baidu.com https://hna-chat.baidu.com https://hnb-chat.baidu.com http://debug.baidu-int.com https://example.com;
-
联系百度: 如果你无法修改当前页面的
CSP
指令,或者希望百度允许更多的域名嵌套他们的页面,你可以联系百度的技术支持,了解是否有其他解决方案,或者请求他们调整他们的CSP
配置。