最近在项目中遇到一个需求需要在一个项目中直接引用另一个项目,尝试各种情况无果后选择了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.

  1. 复制代码

通信(父页面和子页面相互通信)

  两个项目之间相互通信,涉及到跨域问题,子页面不能直接调用父页面的方法,父页面同样不能调用子页面的方法。

错误详情:Error in created hook: "SecurityError: Blocked a frame with origin "http://*" from accessing a cross-origin frame."

解决办法:

  window.postMessage() 方法可以安全地实现跨源通信。该方法被调用时,会在所有页面脚本执行完毕之后向目标窗口派发一个MessageEvent消息。代码如下:

  1.  
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>
  1.  
    复制代码

  上面的例子实现了两个不同域的页面之间的通信。但由于我们此处用的是动态更改iframe.contentWindow.location来访问的内容,如果此处父页面要向子页面发起通信需要在iframe中页面加载完毕以后,不然子页面无法获取到通信数据。

应用场景

  子页面需要调用父页面的方法或则使用父页面的数据时候,我们可以在子页面向父页面发起通信,让父页面调用该方法,或让父页面将数据传输过来。

注意事项

  postMessage支持对象传递,但不是所有浏览器都支持对象传递,在使用中还是使用字符串传值更好。