Skip to content

Commit

Permalink
fix: 修复了通过new Image()创建的元素逃离沙箱的问题 & 修复了通过cloneNode创建的元素逃离沙箱的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
bailicangdu committed Dec 17, 2021
1 parent 931383e commit e9d4f27
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 31 deletions.
9 changes: 9 additions & 0 deletions dev/children/react16/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,12 @@ console.timeEnd('react#16');
// console.log('DOMParser createElement', d1, d2, d3)
// }, 3000)


// // 测试 Image
// const newImg = new Image()
// newImg.src = '/static/media/logo.6ce24c58.svg'
// document.body.appendChild(newImg)

// // 测试 cloneNode
// var img2 = newImg.cloneNode(true)
// document.body.appendChild(img2)
6 changes: 3 additions & 3 deletions dev/main-react16/src/global.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ microApp.start({

// setTimeout(() => {
// unmountAllApps({
// // destroy: true,
// // clearAliveState: true,
// destroy: true,
// clearAliveState: true,
// }).then(() => {
// console.log('unmountAllApps方法 -- 主动卸载所有应用成功')
// })
// }, 50000)
// }, 10000)
4 changes: 2 additions & 2 deletions dev/main-vue2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"core-js": "~3.6.5",
"element-ui": "~2.15.1",
"vue": "^2.6.11",
"vue": "~2.6.11",
"vue-router": "~3.5.1"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ <h4>预加载</h4>
<dl>
<dt>相关地址</dt>
<dd><a target="blank" href="https://github.com/micro-zoe/micro-app/issues">BUG反馈</a></dd>
<dd><a target="blank" href="https://gitter.im/microzoe/micro-app">Gitter群聊</a></dd>
<dd><a target="blank" href="https://gitter.im/microzoe/micro-app">聊天室</a></dd>
<dd><a target="blank" href="https://github.com/micro-zoe/micro-app/discussions">GitHub讨论组</a></dd>
</dl>
<dl>
Expand Down
3 changes: 2 additions & 1 deletion docs/navbar.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
- [主页](/)
- [API](zh-cn/api)
- [常见问题](zh-cn/questions)
- Translations
- [:cn: 中文](/zh-cn/)
- [:uk: English](/en-us/)
3 changes: 1 addition & 2 deletions docs/sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
- [多层嵌套](zh-cn/nest)
- [keep-alive](zh-cn/keep-alive)
- [高级功能](zh-cn/advanced)
- [API](zh-cn/api)
- [路由](zh-cn/route)
- [应用之间跳转](zh-cn/jump)
<!-- - [部署](zh-cn/deploy) -->
Expand All @@ -31,6 +30,6 @@
- [Nuxtjs](zh-cn/framework/nuxtjs)

- 其他
- [API](zh-cn/api)
- [常见问题](zh-cn/questions)
- [更新日志](zh-cn/changelog)
- [讨论区](zh-cn/chat)
5 changes: 5 additions & 0 deletions docs/zh-cn/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
- 🆕 新增了`unmountApp`, `unmountAllApps`方法,用于主动卸载应用。
- 🆕 新增了对`disable-sandbox`, `disable-scopecss`配置的支持。

- **Bug Fix**

- 🐞 修复了通过`new Image()`创建的元素逃离沙箱的问题,fix [#186](https://github.com/micro-zoe/micro-app/issues/186),PR [#187](https://github.com/micro-zoe/micro-app/pull/187) by [asiainfoliwei](https://github.com/asiainfoliwei)
- 🐞 修复了通过`cloneNode`创建的元素逃离沙箱的问题。

- **Update**

- 🚀 优化了元素隔离patch原型链方法相关代码。
Expand Down
2 changes: 1 addition & 1 deletion docs/zh-cn/questions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

微前端框架不是万能的,它的实现原理注定永远无法达到iframe一样的稳定。

所以如果你不知道自己是否需要微前端,那就是不需要!
所以如果你不知道自己是否需要用微前端,就是不需要。

## 2、子应用一定要支持跨域吗?
是的!
Expand Down
4 changes: 3 additions & 1 deletion src/libs/global_env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ declare global {
}

interface Node {
__MICRO_APP_NAME__?: string
__MICRO_APP_NAME__?: string | null
data?: any
}

Expand All @@ -47,6 +47,7 @@ export function initGlobalEnv (): void {
const rawRemoveChild = Element.prototype.removeChild
const rawAppend = Element.prototype.append
const rawPrepend = Element.prototype.prepend
const rawCloneNode = Element.prototype.cloneNode

const rawCreateElement = Document.prototype.createElement
const rawCreateElementNS = Document.prototype.createElementNS
Expand Down Expand Up @@ -89,6 +90,7 @@ export function initGlobalEnv (): void {
rawRemoveChild,
rawAppend,
rawPrepend,
rawCloneNode,
rawCreateElement,
rawCreateElementNS,
rawCreateDocumentFragment,
Expand Down
11 changes: 11 additions & 0 deletions src/sandbox/image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { getCurrentAppName } from '../libs/utils'

const ImageProxy = new Proxy(Image, {
construct: (Target, args): any => {
const elementImage = new Target(...args)
elementImage.__MICRO_APP_NAME__ = getCurrentAppName()
return elementImage
},
})

export default ImageProxy
39 changes: 19 additions & 20 deletions src/sandbox/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import type { microWindowType, SandBoxInterface } from '@micro-app/types';
import type { microWindowType, SandBoxInterface } from '@micro-app/types'
import {
EventCenterForMicroApp, rebuildDataCenterSnapshot, recordDataCenterSnapshot
} from '../interact';
import globalEnv from '../libs/global_env';
} from '../interact'
import globalEnv from '../libs/global_env'
import {
defer, getCurrentAppName, getEffectivePath, isArray, isPlainObject, isString, removeDomScope, setCurrentAppName, unique
} from "../libs/utils";
import microApp from '../micro_app';
import bindFunctionToRawWidow from './bind_function';
import effect, { effectDocumentEvent, releaseEffectDocumentEvent } from './effect';
defer,
getEffectivePath,
isArray,
isPlainObject,
isString,
removeDomScope,
setCurrentAppName,
unique,
} from '../libs/utils'
import microApp from '../micro_app'
import bindFunctionToRawWidow from './bind_function'
import effect, { effectDocumentEvent, releaseEffectDocumentEvent } from './effect'
import ImageProxy from './image'

/* eslint-disable camelcase */
type injectDataType = {
Expand Down Expand Up @@ -58,13 +66,6 @@ function macroTask (fn: TimerHandler): void {
macroTimer = setTimeout(fn, 0)
}

const imageProxy = new Proxy(Image, {
construct: (Target, args): any => {
Target.prototype.__MICRO_APP_NAME__ = getCurrentAppName();
return new Target(...args);
},
});

export default class SandBox implements SandBoxInterface {
static activeCount = 0 // number of active sandbox
// @ts-ignore
Expand Down Expand Up @@ -108,10 +109,6 @@ export default class SandBox implements SandBoxInterface {
return this.proxyWindow
}

if (key === "Image") {
return imageProxy;
}

if (key === 'top' || key === 'parent') {
if (rawWindow === rawWindow.parent) { // not in iframe
return this.proxyWindow
Expand All @@ -121,7 +118,7 @@ export default class SandBox implements SandBoxInterface {

if (key === 'hasOwnProperty') return hasOwnProperty

if (key === 'document' || key === 'eval') {
if (key === 'document' || key === 'eval' || key === 'Image') {
if (this.active) {
setCurrentAppName(appName)
;(macro ? macroTask : defer)(() => setCurrentAppName(null))
Expand All @@ -131,6 +128,8 @@ export default class SandBox implements SandBoxInterface {
return rawDocument
case 'eval':
return eval
case 'Image':
return ImageProxy
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/source/patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,13 @@ export function patchElementPrototypeMethods (): void {

return globalEnv.rawRemoveChild.call(this, oldChild) as T
}

// patch cloneNode
Element.prototype.cloneNode = function cloneNode (deep?: boolean): Node {
const clonedNode = globalEnv.rawCloneNode.call(this, deep)
this.__MICRO_APP_NAME__ && (clonedNode.__MICRO_APP_NAME__ = this.__MICRO_APP_NAME__)
return clonedNode
}
}

/**
Expand Down Expand Up @@ -430,6 +437,7 @@ export function releasePatches (): void {
Element.prototype.removeChild = globalEnv.rawRemoveChild
Element.prototype.append = globalEnv.rawAppend
Element.prototype.prepend = globalEnv.rawPrepend
Element.prototype.cloneNode = globalEnv.rawCloneNode
}

// Set the style of micro-app-head and micro-app-body
Expand Down

0 comments on commit e9d4f27

Please sign in to comment.