Giter VIP home page Giter VIP logo

Comments (21)

yiludege avatar yiludege commented on July 24, 2024 10

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

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,详见讨论

from wujie.

dorasong avatar dorasong commented on July 24, 2024 3

各位大大们,这个问题有解决吗?目前使用无界遇到同样问题了,然后页面卡死了,子应用无法加载,页面一直在loading @所有人

from wujie.

yiludege avatar yiludege commented on July 24, 2024

大家如果有好的方案的话可以在这个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.

gyhyfj avatar gyhyfj commented on July 24, 2024

可否让iframe加载主应用host时请求头上带一个特殊字段,然后主应用如果发现这样的特殊字段就返回个空的txt之类的

from wujie.

taoguili avatar taoguili commented on July 24, 2024

目前的轮询实测经常遇到因为无法及时中止iframe加载,而开始无限嵌套iframe的问题,导致页面无法加载直至卡死,这时控制台会不断输出中止执行的警告。

iframe初始化时候会向主域发出一个请求,这次请求的请求头 referer 字段是主域名,可否通过配置主应用,如果检测到这个referer字段,就返回一个特殊的文件,这样似乎就不必轮询了,也可以通过这个特殊文件里的一段js代码,调用提前放在全局的一个函数,主动通知无界iframe已经准备好了


老板,轮询这个有处理吗?

from wujie.

dorasong avatar dorasong commented on July 24, 2024

目前的轮询实测经常遇到因为无法及时中止iframe加载,而开始无限嵌套iframe的问题,导致页面无法加载直至卡死,这时控制台会不断输出中止执行的警告。

iframe初始化时候会向主域发出一个请求,这次请求的请求头 referer 字段是主域名,可否通过配置主应用,如果检测到这个referer字段,就返回一个特殊的文件,这样似乎就不必轮询了,也可以通过这个特殊文件里的一段js代码,调用提前放在全局的一个函数,主动通知无界iframe已经准备好了

请问有解决相关问题吗?

from wujie.

wang8254 avatar wang8254 commented on July 24, 2024

目前的轮询实测经常遇到因为无法及时中止iframe加载,而开始无限调用iframe的问题,导致页面无法加载请求卡死,随后控制台会不断输出中止执行的警告。
iframe初始化的时候会向主域发出一个请求,这次请求的请求头referer字段是主域名,可以通过配置主应用否决,如果检测到这个referer字段,就返回一个特殊的文件,这样好像就不需要轮询了,也可以通过这个特殊文件里的js代码,调用提前放在全局的一个函数,主动通知无界iframe已经准备好了

请问有解决相关问题吗?

同问,如果暂时没有好的办法,有没有什么方法让它提示一次就行了。或者配置一个属性什么的。不让无限提示

from wujie.

JanusSpark avatar JanusSpark commented on July 24, 2024

子应用如何设置attr?看文档 我一直感觉子应用没啥设置的地方啊

from wujie.

pandaOreo avatar pandaOreo commented on July 24, 2024

attr在哪设置

from wujie.

enmotion avatar enmotion commented on July 24, 2024

这个坑有点大啊,具体怎么解决,能给出范例代码吗?这么看说明,很晦涩

from wujie.

pandaOreo avatar pandaOreo commented on July 24, 2024

from wujie.

Lemonreds avatar Lemonreds commented on July 24, 2024

关注~

from wujie.

baixi233 avatar baixi233 commented on July 24, 2024

@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.

li1037 avatar li1037 commented on July 24, 2024

各位大大们,这个问题有解决吗?目前使用无界遇到同样问题了,然后页面卡死了,子应用无法加载,页面一直在loading @所有人

@dorasong 大佬这个解决了吗,我也遇到一样的问题,/host/empty返回空白内容后,一直显示loading中,也没报错

from wujie.

pandaOreo avatar pandaOreo commented on July 24, 2024

from wujie.

AttackXiaoJinJin avatar AttackXiaoJinJin commented on July 24, 2024

@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.

pandaOreo avatar pandaOreo commented on July 24, 2024

from wujie.

AttackXiaoJinJin avatar AttackXiaoJinJin commented on July 24, 2024

运行主应用的 js 资源污染了 iframe 沙箱

具体是哪些污染呢,可以具体列下吗?我能想到的是:

  • 主应用js调用window.location跳转,导致沙箱被替换
  • 主应用js向window塞了全局对象影响了wujie的全局对象

from wujie.

AttackXiaoJinJin avatar AttackXiaoJinJin commented on July 24, 2024

我试了以下几种方法都不行(痛苦面具):

  • 同时设置 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.

towertop avatar towertop commented on July 24, 2024

我不是太理解这个问题,也没在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.

pandaOreo avatar pandaOreo commented on July 24, 2024

from wujie.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.