簡介
一個運用html5的跨域api postMessage處理一個體系中,多個iframe跨域通訊交互的js庫。
github地點 :cross-domain
背景
最初公司只要一個體系來做販賣,跟着公司營業越來越多,搭建許多相似的體系(這些體系本來是沒有任何關係的,每一個體系如今都異常龐雜)。
因為如今公司計謀有調解,本來的販賣是針對某種產物,如今販賣事情要針對客戶舉行多產物的販賣促進,如許一個販賣職員就需要翻開種種體系舉行營業操縱,異常不方便,而且販賣數據間不能有用通報,所就需要把各個不相關的體系整合在一起,完成跨營業線販賣和數據同享。若將這想要將這些龐雜體系整合在一起,無論是從人力物力上都是不太可能接收的。
所以挑選了運用iframe將各體系嵌入一個框架體系,各體系從物理上照樣離開穩定,而從邏輯上(從用戶角度看就是一個體系)看起來是一個體系。
但是各體系採用了差別的域名,與主框架體系和別的營業體系有跨域題目(若將一切域名改成統一域名下可能會發生一些體系間頁面元素和款式的爭執)
故採用了HTML5規範下的postMessage來處理該題目。
引見
- 示意圖
- http://a.com 是最外層主體系的頁面,為master
- http://b.com 和 http://c.com 為被嵌入的子體系slave,固然也能夠嵌入N個子體系
master和slave都是有各自的域名,因為瀏覽器的平安限制,兩個iframe正常是不能舉行數據交換和api挪用的。固然有一些特別要領如jsonp,iframe name等。假如想相識,能夠看看我的另一篇文章jsonp完成道理 。
在HTML5中新增了postMessage要領,postMessage能夠完成跨文檔音訊傳輸(Cross Document Messaging),Internet Explorer 8, Firefox 3, Opera 9, Chrome 3和 Safari 4都支撐postMessage。postMessage api細緻引見,請檢察 postMessage
示意圖以下:
https://raw.githubusercontent…
供應的重要API
js庫供應了簡約的挪用和供應接口的要領,引見以下
- 接口挪用(向別的iframe發送數據)
/**
* 發送音訊要領
* @param {String} componentName組件稱號
* @param {String} method接口稱號(對方經由過程API extends供應的接口名)
* @param {Object} data數據
* @param {Function} callback回調
*/
send : function(componentName,method,data,callback,type);
- 供應接口(供應前端接口,可供別的iframe挪用)
/**
* 擴大接口要領,供挪用方send要領挪用
* @param {String} name接口稱號
* @param {Function} fun 接口要領
*/
extends : function(name,fun);
例子
- Master代碼以下
啟動http效勞,http://localhost/cross-domain…
<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--引入js庫-->
<script type="text/javascript" src="../src/cross-domain.js"></script>
</head>
<body>
Test Page MASTER
<button onclick="sendMesg1()">send data to Slave1</button>
<button onclick="sendMesg2()">send data to Slave2</button>
<br/>
<!--slave1-->
<iframe src="http://127.0.0.1/cross-domain/example/slave1.html" name="SLAVE1" id="SLAVE1"></iframe>
<!--slave2-->
<iframe src="http://127.0.0.1/cross-domain/example/slave2.html" name="SLAVE2" id="SLAVE2"></iframe>
<div id="content"></div>
</body>
<script type="text/javascript">
var me = CD.component.name;
function genInfo(name){
return {info : "Hello [" + name + "] , I am [" + me + "] Now at " + new Date()};
}
//挪用SLAVE2的changeSlave1前端接口,接口參數為genInfo("SLAVE1")
function sendMesg1 (argument) {
CD.send("SLAVE1" , "changeSlave1" ,genInfo("SLAVE1") ,function(data){
console.log("callback fire");
writeHtml(data);
});
}
//挪用SLAVE2的changeSlave2前端接口,接口參數為genInfo("SLAVE2")
function sendMesg2 (argument) {
CD.send("SLAVE2" , "changeSlave2" , genInfo("SLAVE2"));
}
//MASTER供應接口,可供SLAVE1和SLAVE2挪用
CD.extends("changeMaster" , function(data){
writeHtml(data.info);
});
//當SLAVE1和SLAVE2挪用changeMaster接口時,會打印在MASTER的頁面中
function writeHtml(text){
var content = document.getElementById("content");
content.innerHTML += "<br/>" + text;
}
console.log(CD);
</script>
</html>
- Slave1
啟動http效勞,http://127.0.0.1/cross-domain…
<!DOCTYPE html>
<html>
<head>
<title>slave1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="../src/cross-domain.js"></script>
</head>
<body>
<div id="main">
I am salve1 frame
<button onclick="sendMesg()">send data</button>
</div>
<div id="content"></div>
</body>
<script type="text/javascript">
var me = CD.component.name;
function genInfo(name){
return {info : "Hello [" + name + "] , I am [" + me + "] Now at " + new Date()};
}
//挪用MASTER的changeMaster接口,數據為genInfo("MESTER")
function sendMesg (argument) {
CD.send("MESTER" , "changeMaster" ,genInfo("MESTER"));
}
//供應前端接口changeSlave1,可供MASTER和別的SLAVE挪用
CD.extends("changeSlave1" , function(data){
writeHtml(data.info);
return "Slave1 changeSlave1 is called";
});
function writeHtml(text){
var content = document.getElementById("content");
content.innerHTML += "<br/>" + text;
}
console.log(CD);
</script>
</html>
- Slave2
啟動http效勞,http://127.0.0.1/cross-domain…
<!DOCTYPE html>
<html>
<head>
<title>slave2</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="../src/cross-domain.js"></script>
</head>
<body>
<div id="main">
I am slave2 frame
<button onclick="sendMesg()">send data</button>
</div>
<div id="content"></div>
</body>
<script type="text/javascript">
var me = CD.component.name;
function genInfo(name){
return {info : "Hello [" + name + "] , I am [" + me + "] Now at " + new Date()};
}
//挪用MASTER的changeMaster接口,數據為genInfo("MESTER")
function sendMesg (argument) {
CD.send("MESTER" , "changeMaster" ,genInfo("MESTER"));
}
//供應前端接口changeSlave2,可供MASTER和別的SLAVE挪用
CD.extends("changeSlave2" , function(data){
writeHtml(data.info);
});
function writeHtml(text){
var content = document.getElementById("content");
content.innerHTML += "<br/>" + text;
}
console.log(CD);
</script>
</html>
- 交互結果
運用案例
某企業作業體系