function sendMsg(originURL, msg){
var data = {fromriginURL, msg:msg};
var src = originURL + “#” + dojo.toJson(data);
document.getElementById('domainB').src=src;
}
B 中的函数将轮询自身的 hash 值,找出 A 发送的是什么,然后它可以用同样的方式回复 A。如果 A 想接收这条消息,也需要轮询其本身的 hash 值。
清单 2. 监视 url.hash 并从中接收信息
function sendMsg(originURL, msg){
…
var src = originURL + “#” + encodeURI (dojo.toJson(data));
…
}
接收时,应先进行解码。
清单 4. Receiving message containing special characters
1
2
3
4
5
function checkMsg(){
…
var msgs = decodeURI(dojo.fromJson(newHash));
…
}
Cross-fragment 技术由于许多网站将 hash 用于其他用途,对于这些网站来说,要将 URL.hash(fragment id) 技术并入跨域通信和数据传输是比较复杂的。跨帧 (Cross-frame) 信息传递有点类似片段 id 信息传递。图 4 显示了跨段 (cross-fragment) 是如何起作用的。
图 4. 跨段技术在上图中,当 A 想要与 iframe B 进行通信时,会先在其自身中创建一个 iframe。这个 iframe 指向与 B 位于同一域中的 “代理” C。代理 URL 中包含参数、数据以及 B 的框架标识符。
清单 5. 使用跨段技术发送消息
1
2
3
4
5
6
7
8
function sendMsg(msg){
var frame = document.createElement(“iframe”);
var baseProxy = “http://www.otherapp.com/proxy.html”;
var request = {frameName:’otherApp’,data:msg};
frame.src = baseProxy+”#”+encodeURI (dojo.toJson(request));
frame.style.display=”none”;
document.body.appendChild(frame);
}
当 C 加载信息时,它会从 A 中获取请求和数据并调用 B 中相应的方法。由于 B 和 C 在相同的域中,所以可以通过另一个窗口的处理程序直接调用对方的方法。A 可以成功地向 B 发送信息,B 也可以用同样的方式进行响应。
清单 6. 使用 cross-fragment 技术接收消息
1
2
3
4
5
6
7
8
9
10
window.onLoad = function(){
var hash = window.location.hash;
if(hash && hash.length>1){
var request = hash.substring(1,hash.length);
var obj = dojo.fromJson(decodeURI (request));
var data = obj.data;
//process data
parent.frames[obj.frameName].getData(…);// getData in a function defined in B
}
}
OpenAjax 实现OpenAjax 提供了托管集线器模块,以支持基于 fragment id 和 cross-frame 技术的跨域通信和数据传输。托管集线器模块包括管理器端和客户端。托管集线器中包含一个消息集线器,用于存储消息。每一个想要与其他部件通信的小部件都需要在自身建立一个集线器客户端,并且还需建立一个相应的容器来连接它。该容器将与代表客户端的托管集线器进行交互。客户端可以利用订阅/发布机制发送和接收消息。OpenAjax 的基本工作流如图 5 所示。
图 5. OpenAjax 的主要工作流