首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

利用客户端解决方案改进跨域通信(2)URL.hash(fragment id) 解决方案

利用客户端解决方案改进跨域通信(2)URL.hash(fragment id) 解决方案

URL.hash(fragment id) 解决方案一个 URL 由几部分组成,如下图 2 所示:
图 2.  URL 组件通常,URL 的任何更改都会导致加载新的页面。唯一的例外是 hash 值的变化。任何 URL 的 hash 更改都不会导致页面刷新。许多 Web 2.0 网站中都已经开始广泛使用 Hash,以标记部分刷新页面时的每一个步骤。在跨域通信中,hash 是一笔宝贵的资产。虽然在获取对方 hash 值方面有一些限制,但来自不同源点的文件可以设置对方的 URL,包括 hash 值。文档相互之间可以使用 hash 传送信息。图 3 显示了一个示例。
图 3. 使用 URL.hash(fragment id) 进行通信在图 3 中,当 A 想要向 B 发送信息时,它可以修改 B 的 hash 值,如清单 1 所示:
清单 1. 通过 url.hash 发送信息
1
2
3
4
5
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 并从中接收信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
window.oldHash="";
checkMessage = function(){
    var newHash = window.location.hash;
    if(newHash.length > 1){
        newHash = newHash.substring(1,newHash.length);
        if(newHash != oldHash){
        oldHash = newHash;
        var msgs = dojo.fromJson(newHash);
        var origin = msgs.from;
        var msg = msgs.msg;
             sendMessage(origin, "Hello document A");
         }
    }
}
window.setInterval(checkMessage, 1000);
sendMessage = function(target, msg){
    var hash = "msg="+ msg;
    parent.location.href= target + “#” + hash;
}




像 JSONP 一样,这种方法也有一个长度限制,但它可以更好地处理错误。一些特殊字符,比如问号(?),是 URL 中的保留字符,应先对这些字符进行编码。
清单 3. 通过 url.hash 发送包含特殊符号的信息
1
2
3
4
5
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 的主要工作流
返回列表