最近在项目中遇到一个需求需要在一个项目中直接引用另一个项目,尝试各种情况无果后选择了iframe。现将调用过程中遇到的问题做一个分享。
router.go()的使用
此情况主要适用于更改iframe中src值以后导致的路由跳转混乱。
详细描述:当多次更改iframe->src属性后,调用router.go(-1),不能实现路由后退上一级,而是将iframe当作一个窗口文档,调用了该窗口文档的window.history.go(-1),并未更改父级项目的路由后退功能。
解决办法:
不通过改变iframe->src属性值去访问具体内容,采用window.location.replace(url)更改iframe将访问的内容,具体代码如下:
1.
2.
<template>
3.
<iframeref="iframe"scrolling="auto"width="100%"height="100%"frameborder="0"</iframe>
4.
</template>
5.
<script>
6.
exportdefault {
7.
name: 'ComponentsName',
8.
data() {
9.
return {
10.
url: ''
11.
}
12.
},
13.
watch: {
14.
url(val) {
15.
if (val) {
16.
this.$refs.iframe.contentWindow.location.replace(val)
17.
}
18.
}
19.
}
20.
}
21.
</script>
22.
复制代码
通信(父页面和子页面相互通信)
两个项目之间相互通信,涉及到跨域问题,子页面不能直接调用父页面的方法,父页面同样不能调用子页面的方法。
错误详情:Error in created hook: "SecurityError: Blocked a frame with origin "http://*" from accessing a cross-origin frame."
解决办法:
window.postMessage() 方法可以安全地实现跨源通信。该方法被调用时,会在所有页面脚本执行完毕之后向目标窗口派发一个MessageEvent消息。代码如下:
1.
<!DOCTYPE html>
2.
<html>
3.
<head>
4.
<title>Post Message</title>
5.
</head>
6.
<body>
7.
<div>
8.
<divid="color">Frame Color</div>
9.
</div>
10.
<div>
11.
<iframeid="child"width="50%"src="http://172.16.110.188/test.html"height="50vw"scrolling="auto"frameborder="0"></iframe>
12.
</div>
13.
<scripttype="text/javascript">
14.
window.οnlοad=function(){
15.
document.getElementById('child').contentWindow.postMessage('getcolor','http://172.16.110.188');
16.
}
17.
window.addEventListener('message',function(e){
18.
var color=e.data;
19.
document.getElementById('color').style.backgroundColor=color;
20.
},false);
21.
</script>
22.
</body>
23.
</html>
24.
复制代码
25.
<!-- test.html -->
26.
<!doctype html>
27.
<html>
28.
<head>
29.
<styletype="text/css">
30.
html,body{
31.
height:100%;
32.
margin:0px;
33.
}
34.
#container{
35.
widht:100%;
36.
height:100%;
37.
background-color:rgb(204, 102, 0);
38.
}
39.
</style>
40.
</head>
41.
<bodystyle="height:100%;">
42.
<divid="container"onclick="changeColor();">
43.
click to change color
44.
</div>
45.
<scripttype="text/javascript">
46.
vardocument.getElementById('container');
47.
window.addEventListener('message',function(e){
48.
if(e.source!=window.parent) return;
49.
var color=container.style.backgroundColor;
50.
window.parent.postMessage(color,'*');
51.
},false);
52.
functionchangeColor) {
53.
var color=container.style.backgroundColor;
54.
if(color=='rgb(204, 102, 0)'){
55.
color='rgb(204, 204, 0)';
56.
}else{
57.
color='rgb(204,102,0)';
58.
}
59.
container.style.backgroundColor=color;
60.
window.parent.postMessage(color,'*');
61.
}
62.
</script>
63.
</body>
64.
</html>
-
复制代码
上面的例子实现了两个不同域的页面之间的通信。但由于我们此处用的是动态更改iframe.contentWindow.location来访问的内容,如果此处父页面要向子页面发起通信需要在iframe中页面加载完毕以后,不然子页面无法获取到通信数据。
应用场景
子页面需要调用父页面的方法或则使用父页面的数据时候,我们可以在子页面向父页面发起通信,让父页面调用该方法,或让父页面将数据传输过来。
注意事项
postMessage支持对象传递,但不是所有浏览器都支持对象传递,在使用中还是使用字符串传值更好。