最近在项目中遇到一个需求须要在一个项目中直接引用另外一个项目,尝试各类状况无果后选择了iframe。现将调用过程当中遇到的问题作一个分享。javascript
此状况主要适用于更改iframe中src值之后致使的路由跳转混乱。css
详细描述:当屡次更改iframe->src属性后,调用router.go(-1),不能实现路由后退上一级,而是将iframe看成一个窗口文档,调用了该窗口文档的window.history.go(-1),并未更改父级项目的路由后退功能。html
解决办法:vue
不经过改变iframe->src属性值去访问具体内容,采用window.location.replace(url)更改iframe将访问的内容,具体代码以下:java
<!-- A.html -->
<template>
<iframe ref="iframe" scrolling="auto" width="100%" height="100%" frameborder="0" ></iframe>
</template>
<script> export default { name: 'ComponentsName', data() { return { url: '' } }, watch: { url(val) { if (val) { this.$refs.iframe.contentWindow.location.replace(val) } } } } </script>
复制代码
两个项目之间相互通讯,涉及到跨域问题,子页面不能直接调用父页面的方法,父页面一样不能调用子页面的方法。跨域
错误详情:Error in created hook: "SecurityError: Blocked a frame with origin "http://*" from accessing a cross-origin frame."浏览器
解决办法: postMessage安全
window.postMessage() 方法能够安全地实现跨源通讯。该方法被调用时,会在全部页面脚本执行完毕以后向目标窗口派发一个MessageEvent消息。代码以下:post
<!-- 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://172.16.110.188/test.html" height="50vw" scrolling="auto" frameborder="0"></iframe>
</div>
<script type="text/javascript"> window.onload=function(){ document.getElementById('child').contentWindow.postMessage('getcolor','http://172.16.110.188'); } window.addEventListener('message',function(e){ var 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"> var container=document.getElementById('container'); window.addEventListener('message',function(e){ if(e.source!=window.parent) return; var color=container.style.backgroundColor; window.parent.postMessage(color,'*'); },false); function changeColor () { var 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>
复制代码
上面的例子实现了两个不一样域的页面之间的通讯。但因为咱们此处用的是动态更改iframe.contentWindow.location来访问的内容,若是此处父页面要向子页面发起通讯须要在iframe中页面加载完毕之后,否则子页面没法获取到通讯数据。ui
子页面须要调用父页面的方法或则使用父页面的数据时候,咱们能够在子页面向父页面发起通讯,让父页面调用该方法,或让父页面将数据传输过来。
postMessage支持对象传递,但不是全部浏览器都支持对象传递,在使用中仍是使用字符串传值更好。