最近在項目中遇到一個需求須要在一個項目中直接引用另外一個項目,嘗試各類狀況無果後選擇了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支持對象傳遞,但不是全部瀏覽器都支持對象傳遞,在使用中仍是使用字符串傳值更好。