Comments (21)
这是一个很好的问题,目前也是无界的一个无法解决的点。
1、子应用需要一个 空白的、同域的、浏览器前进后退可以生效的 iframe 作为沙箱。
2、无界采用直接加载 iframe src 等于主应用 host 的地址,然后等 window.location 初始化成主应用域名后(为了子应用路由 window.history.pushState 可以正常工作)后立即停止iframe的加载,此时子应用跳转路由后点击浏览器后退也可以生效到子应用
3、但是在等待 location origin 初始化的过程中有可能加载了主应用 host 地址的 html,然后运行了这个地址内的部分代码,在 safari 浏览器中尤其明显:
- iframe 加载主应用 host 以及资源
- iframe 加载主应用 host 和资源后运行了主应用的js
无界框架做了兜底方案,发现主应用代码在子应用中运行会直接抛错中断运行
4、 location origin 一旦完成初始化,无界会清空这个iframe,注入子应用的代码进行执行
所以现在的问题是如何得到一个空白的、同域的、浏览器前进后退可以生效的 iframe
方案 1:主应用提供一个路径比如说 https://host/empty
,这个路径返回不包含任何内容,子应用设置 attr 为{src:'https://host/empty'}
,这样 iframe 的 src 就是 https://host/empty
,不会存在污染问题, 阿里 Alfa也有类似方案
方案2:通过纯粹的 js 实现 一个 空白的、同域的、浏览器前进后退可以生效的 iframe,详见讨论
from wujie.
各位大大们,这个问题有解决吗?目前使用无界遇到同样问题了,然后页面卡死了,子应用无法加载,页面一直在loading @所有人
from wujie.
大家如果有好的方案的话可以在这个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,但是浏览器前进后退无法作用到子应用
from wujie.
可否让iframe加载主应用host时请求头上带一个特殊字段,然后主应用如果发现这样的特殊字段就返回个空的txt之类的
from wujie.
目前的轮询实测经常遇到因为无法及时中止iframe加载,而开始无限嵌套iframe的问题,导致页面无法加载直至卡死,这时控制台会不断输出中止执行的警告。
iframe初始化时候会向主域发出一个请求,这次请求的请求头
referer
字段是主域名,可否通过配置主应用,如果检测到这个referer字段,就返回一个特殊的文件,这样似乎就不必轮询了,也可以通过这个特殊文件里的一段js代码,调用提前放在全局的一个函数,主动通知无界iframe已经准备好了
老板,轮询这个有处理吗?
from wujie.
目前的轮询实测经常遇到因为无法及时中止iframe加载,而开始无限嵌套iframe的问题,导致页面无法加载直至卡死,这时控制台会不断输出中止执行的警告。
iframe初始化时候会向主域发出一个请求,这次请求的请求头
referer
字段是主域名,可否通过配置主应用,如果检测到这个referer字段,就返回一个特殊的文件,这样似乎就不必轮询了,也可以通过这个特殊文件里的一段js代码,调用提前放在全局的一个函数,主动通知无界iframe已经准备好了
请问有解决相关问题吗?
from wujie.
目前的轮询实测经常遇到因为无法及时中止iframe加载,而开始无限调用iframe的问题,导致页面无法加载请求卡死,随后控制台会不断输出中止执行的警告。
iframe初始化的时候会向主域发出一个请求,这次请求的请求头referer
字段是主域名,可以通过配置主应用否决,如果检测到这个referer字段,就返回一个特殊的文件,这样好像就不需要轮询了,也可以通过这个特殊文件里的js代码,调用提前放在全局的一个函数,主动通知无界iframe已经准备好了请问有解决相关问题吗?
同问,如果暂时没有好的办法,有没有什么方法让它提示一次就行了。或者配置一个属性什么的。不让无限提示
from wujie.
子应用如何设置attr?看文档 我一直感觉子应用没啥设置的地方啊
from wujie.
attr在哪设置
from wujie.
这个坑有点大啊,具体怎么解决,能给出范例代码吗?这么看说明,很晦涩
from wujie.
from wujie.
关注~
from wujie.
@yiludege 个人觉得能这样处理 #751
iframe = document.createElement('iframe')
iframe.src = URL.createObjectURL(new Blob())
iframe.style.display = 'none'
document.body.appendChild(iframe)
iframe.onload = () => {
// pushState功能及监听
win = iframe.contentWindow
win.addEventListener('popstate',e => console.log('popstate',e))
win.history.pushState({},"")
win.history.back()
// 跨域测试
console.log(win.location)
win.fetch('https://www.baidu.com').then(t => t.text()).then(console.log)
}
meaningless = null
from wujie.
各位大大们,这个问题有解决吗?目前使用无界遇到同样问题了,然后页面卡死了,子应用无法加载,页面一直在loading @所有人
@dorasong 大佬这个解决了吗,我也遇到一样的问题,/host/empty返回空白内容后,一直显示loading中,也没报错
from wujie.
from wujie.
@JanusSpark @pandaOreo 传props:https://wujie-micro.github.io/doc/api/startApp.html#attrs
await startApp({
...props,
attrs:{
// 主应用路由返回空内容
src:'http://localhost:3000/xxx'
},
el:myRef.current,
});
<WujieReact
attrs={{
// 主应用路由返回空内容
src:'http://localhost:3000/xxx'
}}
/>
from wujie.
from wujie.
运行主应用的 js 资源污染了 iframe 沙箱
具体是哪些污染呢,可以具体列下吗?我能想到的是:
- 主应用js调用window.location跳转,导致沙箱被替换
- 主应用js向window塞了全局对象影响了wujie的全局对象
from wujie.
我试了以下几种方法都不行(痛苦面具):
- 同时设置 src 和 srcdoc,在 srcdoc 里写 script 移除 srcdoc,可以不让 src 加载资源,但 iframe.contentWindow.location 是 srcdoc,要想修改 location,只能显式写
iframe.src=主应用host
(还是得加载主应用 host) - 在上面的基础上,使用 history.replaceState 修改 url 以达到修改 location 的目的,但该 api 只允许同源修改 path,不能修改 host(说白了还是得先加载主应用 host)
- 创建 iframe 时,使用 iframe 的 sandbox 属性禁止脚本加载,以达到禁止加载主应用的 js ,在 iframe onload 时移除 sandbox 属性,以方便 wujie js 执行,但即使移除了 sandbox,iframe 仍然延续 sandbox 属性的,除非再一次执行 iframe.src(还是得加载主应用 host)
- 通过 js 劫持 iframe 的网络请求,但 gpt 说 iframe.src 请求是浏览器级别发起的,js 没有权限
from wujie.
我不是太理解这个问题,也没在Chrome上复现和观测到。但我加上了方案1的设置,{attrs: { src: "/iframe.html"}}
,iframe是在宿主应用写的一个静态的空白文件,观测子应用加载后iframe加载了这个html文件,之后子应用内的 history.pushState 等都可以正常使用,但回退按钮异常。
不太确定 aliyun/alibabacloud-alfa#99 中提到的“当子应用跳转路由后点击浏览器后退发现无效“这是什么现象。我现在在保活模式下,路由之后回退按钮下的历史会有很多条,并且回退1次正常,但是前进按钮下会多出很多记录,并且回退2次时整个应该直接被chrome退到了newtab(比如默认搜索)页面,偶尔也见到回退按钮直接变灰禁用。
我认为跟 Chrome 等浏览器厂商实现的回退过程中一些启发式跳过的算法有关,也许是子应用的sync同步引发的,有待进一步调查:whatwg/html#7832 。
from wujie.
from wujie.
Related Issues (20)
- 多层嵌套 HOT 1
- 主应用、子应用均为Vue2,子应用引入使用bpmn-js生成流程图,在火狐浏览器下,主应用嵌入子应用时不显示流程图。 HOT 5
- wujievue2 为什么不导出startApp HOT 1
- 子应用不能监听自定义合成事件 HOT 5
- 微前端对于write不支持 HOT 1
- 微信h5使用wujie后,在子应用展示二维码,ios长按二维码无响应,无法实现保存,分享,转发等操作,安卓正常 HOT 2
- 子应用引用第三方cdn静态js资源,加载出现跨域问题 HOT 1
- 无界 保活模式 一段时间不操作页面 #子应用出现边框且页面卡死,而且WujieVue.bus.$emit也无法触达子应用。 HOT 12
- 官网demo,子应用字体在重新激活时加载重复,生成两个一模一样的style标签
- 孙子应用的自定义@font-face不生效
- 子应用弹窗显示不了图片,position:fixed;或者absolute的时候不能展示图片。都是用的vue2,双向绑定也没问题就是渲染的时候img表情的src是空的
- window.$wujie.location.href 跳转问题 HOT 1
- 子应用中Popconfirm的确认事件无法被正确触发 HOT 2
- 这个仓库还在维护吗 HOT 9
- 子应用中使用 document.documentElement.addEventListener('keydown', ()=>{}) 绑定事件不生效
- wujie中无法正常是用worker HOT 5
- 子应用中鼠标事件获取offset的值是基于wujie-app,不是基于指定元素
- vue3什么时候可以作为基座 HOT 1
- 子应用偶现白屏,且无报错 HOT 1
- 子应用打包部署后,antd组件库样式问题 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from wujie.