wujie icon indicating copy to clipboard operation
wujie copied to clipboard

加载完子应用入口html后为何还要请求一次主应用host

Open handoing opened this issue 3 years ago • 23 comments

描述bug 加载完子应用入口html后为何还要请求一次主应用host

handoing avatar Aug 12 '22 05:08 handoing

这是一个很好的问题,目前也是无界的一个无法解决的点。

1、子应用需要一个 空白的、同域的、浏览器前进后退可以生效的 iframe 作为沙箱。

2、无界采用直接加载 iframe src 等于主应用 host 的地址,然后等 window.location 初始化成主应用域名后(为了子应用路由 window.history.pushState 可以正常工作)后立即停止iframe的加载,此时子应用跳转路由后点击浏览器后退也可以生效到子应用

3、但是在等待 location origin 初始化的过程中有可能加载了主应用 host 地址的 html,然后运行了这个地址内的部分代码,在 safari 浏览器中尤其明显:

  • iframe 加载主应用 host 以及资源

image

  • iframe 加载主应用 host 和资源后运行了主应用的js

image

无界框架做了兜底方案,发现主应用代码在子应用中运行会直接抛错中断运行

4、 location origin 一旦完成初始化,无界会清空这个iframe,注入子应用的代码进行执行

所以现在的问题是如何得到一个空白的、同域的、浏览器前进后退可以生效的 iframe

方案 1:主应用提供一个路径比如说 https://host/empty ,这个路径返回不包含任何内容,子应用设置 attr{src:'https://host/empty'},这样 iframe 的 src 就是 https://host/empty,不会存在污染问题, 阿里 Alfa也有类似方案

方案2:通过纯粹的 js 实现 一个 空白的、同域的、浏览器前进后退可以生效的 iframe,详见讨论

yiludege avatar Aug 12 '22 07:08 yiludege

大家如果有好的方案的话可以在这个issue提供一下,下面是背景介绍

介绍:

1、无界微前端采用 iframe 作为沙箱,需要一个空白、主应用同域、不运行主应用 js 代码的 iframe

2、子应用在 iframe 内部运行,当子应用跳转路由时会调用window.history.pushState、window.history.replaceState 等方法,如果 iframe 没有设置 src 的话其 location 为 about:blank 会报跨域错误,因为 location.origin 是 about:blank,而跳转过去的路由是具体的 url

3、无界一般设置 iframe 的 src 为主应用的 host,劫持子应用调用window.history.pushState、window.history.replaceState,将跳转的 url 的域名替换成主应用的 host,这样子应用路由就可以正常跳转

4、但是设置 iframe 的 src 为主应用的 host 会导致 iframe 加载、运行主应用的 js 资源污染了 iframe 沙箱

5、无界这边是采用轮询的方式一旦 iframe 的 location 初始化完成就立即停止加载,但还是无法避免污染问题

具体内容:

1、实现一个空白、主应用同域、不运行主应用 js 代码的 iframe

2、子应用运行在 iframe 沙箱内,浏览器前进后退可以作用到子应用

目前尝试:

1、将 iframe 的src 设置为 主应用的 host

2、将 iframe 插入到 dom 之后立即运行 iframe.contentDocument.open();iframe.contentDocument.write("");iframe.contentDocument.close(),可以得到一个空白、主应用同域、不运行主应用 js 代码的 iframe,但是浏览器前进后退无法作用到子应用

yiludege avatar Nov 23 '22 08:11 yiludege