iframe 使用注意事项
-
src
属性不支持混用http
和https
协议 - 使用
@load
来判断frame
是否加载完毕,相当于iframe<htmlElement>.onload
方法 - 获取嵌套页面关联数据必须使用
iframe<htmlElement>.contentWindow
方法,此方法存在跨域限制,需在外层页面配置代理
<template>
<iframe id="frame" ref="frame" src="http://city.test.uupt.com/#/pages/orderlist" frameborder="0" scrolling="no" @load="loaded"></iframe>
</template>
<script>
export default {
methods: {
loaded() {
console.clear()
console.log('Debugger: this.$refs.frame', this.$refs.frame.contentWindow)
},
},
}
</script>
<style lang="scss">
#frame {
width: 100%;
height: 100%;
}
</style>
- 注意路由跳转混乱
在动态更改 iframe
中 src
后导致路由跳转混乱,当多次更改 iframe
src
属性后,调用 router.go(-1)
并不能实现路由后退一级,而是将 iframe
当作一个窗口文档,调用了 iframe
的 window.history.go(-1)
而并未更改父页面的路由后退功能
此问题可以通过不使用更改 iframe
src
属性的方式来访问具体内容,使用 window.location.replace(url)
更改 iframe 将访问的内容
- 父子页面通信
两个项目之间相关数据通信,由于浏览器跨域限制,子页面不可直接调用父页面方法,父页面同样不能调用子页面的方法
在确定 iframe
已经加载完毕后,可以使用 window.postMessage()
方法实现跨源数据通信,调用此方法后会在所有页面脚本执行完毕后向目标窗口派发一个 MessageEvent
消息
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Post Message</title>
</head>
<body>
<div>
<div id="color">Frame Color</div>
</div>
<div>
<iframe id="child" width="50%" src="http://localhost:3000//test.html" height="50vw" scrolling="auto" frameborder="0"></iframe>
</div>
<script type="text/javascript">
window.onload = function () {
document.getElementById('child').contentWindow.postMessage('getcolor', 'http://localhost:3000/')
}
window.addEventListener(
'message',
function (e) {
const color = e.data
document.getElementById('color').style.backgroundColor = color
},
false
)
</script>
</body>
</html>
<!-- test.html -->
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html,
body {
height: 100%;
margin: 0px;
}
#container {
widht: 100%;
height: 100%;
background-color: rgb(204, 102, 0);
}
</style>
</head>
<body style="height:100%;">
<div id="container" onclick="changeColor()">click to change color</div>
<script type="text/javascript">
const container = document.getElementById('container')
window.addEventListener(
'message',
function (e) {
if (e.source != window.parent) return
const color = container.style.backgroundColor
window.parent.postMessage(color, '*')
},
false
)
function changeColor() {
const color = container.style.backgroundColor
if (color == 'rgb(204, 102, 0)') {
color = 'rgb(204, 204, 0)'
} else {
color = 'rgb(204,102,0)'
}
container.style.backgroundColor = color
window.parent.postMessage(color, '*')
}
</script>
</body>
</html>
适用于子页面需要调用父页面方法活使用父页面数据的场景,可以使用此方法在子页面向父页面发起通信,让父页面调用该方法,接收父页面相关数据
- postMessage
postMessage
支持对象传递,但是由于对象传递存在浏览器差异,建议使用字符串传值