Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 适配domain修改 #310

Merged
merged 1 commit into from
Dec 27, 2022
Merged

Conversation

Xusenbiao
Copy link
Contributor

@Xusenbiao Xusenbiao commented Dec 6, 2022

  • 提交符合commit规范
  • 测试用例添加
  • npm run test通过
详细描述

对于一些使用了iframe的主应用/子应用,可能会通过修改document.domain的方式指定二级域以放宽“同源限制”,从而操作iframe内的文档。
然而这个方式会对wujie的同域iframe产生影响:在创建iframe后的极短时间内移除掉注入到iframeWindow上的属性,从而导致子应用加载失败。
我怀疑这与iframe错误文档陷阱有关。
在验证的过程中发现以下细节:
1、不管是否修改过domain,如果是在iframedocument真正准备好之后往iframeWindow上注入属性,则不会被移除。
2、不管是否修改过domainiframe错误文档陷阱都存在,但如果主应用修改过domain,错误文档停留的时间明显更长。
3、不修改domain场景下,没有移除iframeWindow属性的现象

因此,这个PR尝试兼容domain的修改,兼容后与iframedomain的要求基本一致:
1、如果是主应用希望修改domain放宽“同源限制”
主应用中原来iframe的用法不变。
主应用可正常使用wujie加载子应用,且子应用的domain自动变为主应用修改的domain

2、如果是wujie加载的某个子应用希望修改domain,并在子应用内使用iframe
应该改为在wujie主应用中修改domain,子应用则可以不改(会继承主应用的)。

@yiludege
Copy link
Collaborator

yiludege commented Dec 6, 2022

感觉还是有点不太明白兼容domain的修改的意思是啥...

看issue的描述,应该子应用已经加载完成后设置domain还是会导致报错,这个应该和 iframe错误文档陷阱没有关系吧(毕竟子应用的iframe沙箱已经ready了)

而看修改的代码有两个方面:

一方面是修改子应用 iframe ready的时机(看看是否有新doc),这个是我之前没有想到的,不知道在IE11是否会有问题

一方面如果 iframewindow.__wujie 没有的话重新注入遍历,我不太理解为啥之前已经注入了还会没有,毕竟错误文档陷阱指的是document,挂在到 window 上的变量不应该没有了呀

@Xusenbiao
Copy link
Contributor Author

Xusenbiao commented Dec 7, 2022

感觉还是有点不太明白兼容domain的修改的意思是啥...

看issue的描述,应该子应用已经加载完成后设置domain还是会导致报错,这个应该和 iframe错误文档陷阱没有关系吧(毕竟子应用的iframe沙箱已经ready了)

而看修改的代码有两个方面:

一方面是修改子应用 iframe ready的时机(看看是否有新doc),这个是我之前没有想到的,不知道在IE11是否会有问题

一方面如果 iframewindow.__wujie 没有的话重新注入遍历,我不太理解为啥之前已经注入了还会没有,毕竟错误文档陷阱指的是document,挂在到 window 上的变量不应该没有了呀

抱歉,可能没表达清楚,那个issue #245 描述的场景可以这么验证:
examples/main-vue/public/index.html中加上<script>window.document.domain = 'localhost';</script>指定二级域。本地启动工程后,将看到无法加载子应用,并在控制台可以看到因iframeWindow.__WUJIE变成undefined而引发的报错。

而这个PR正是希望能兼容这种场景。

关于PR的两个改动:
1、调整Iframe ready的时机为document准备好
这是因为如果主应用修改了domain,在Iframedocument没准备好时读取location.href在我这会报跨域问题。

2、如果iframeWindow的__WUJIE属性被移除则重新注入
这是兼容修改domain场景下,iframeWindow的属性会被自动移除的现象。
遗憾的是目前我没找到iframe对这现象的相关说明,于是针对同域iframe进行了如下验证:

    const iframe = window.document.createElement("iframe");
    iframe.setAttribute("src", "http://localhost:8000/test.html") // 一个在相同public目录下的简单html
    window.document.body.appendChild(iframe);

    iframe.contentWindow.testAttr = 1;

    let oldDoc = iframe.contentDocument;
    let timer1 = setInterval(() => {
      let newDoc = iframe.contentDocument;
      if (newDoc == oldDoc) {
        console.log("旧文档!")
      } else {
        clearInterval(timer1);
        console.log("新文档!")
      };
    }, 1);

    let timer2 = setInterval(() => {
      if (iframe.contentWindow.testAttr) {
        console.log("window属性未移除!")
      } else {
        clearInterval(timer2);
        console.log("window属性移除!")
      };
    }, 1);

分别测试内外都修改<script>window.document.domain = 'localhost';</script>和内外都不修改domain的场景(只修改一方会因同源策略报跨越)。
发现都修改domain场景下,文档更新和移除window属性的时机几乎完全一致。
而在不修改domain的场景下,文档会在更短的时间内更新,但不存在移除window属性的现象。

@yiludege

@squallliu
Copy link
Contributor

squallliu commented Dec 21, 2022

@yiludege 这个问题我在兼容IE的时候就遇见过(stopIframeLoading过程中,__wujie会丢失),所以我改了iframeGenerator 整个初始化的流程,但是合并后并没有这部分内容

@yiludege yiludege merged commit ac18816 into Tencent:master Dec 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants