easyXDM实现跨域请求

之前在使用JavaScript创建REST风格的应用程序一文中提到了前端JavaScript跨域请求REST API的解决方案,不过,那是在服务器端配置许可列表。

如果需要在客户端两个不同域名的窗口之间传送数据,采取的解决方案有两类,一是浏览器事件机制,包括window.postMessage接口,但IE8是不支持window.postMessage,只能借助Flash等浏览器插件事件。另外一类是通过向当前DOM注入一个iframe,刷新iframe的url调用回调函数取得跨域的值。很多广告平台的代码都是通过后者来实现用户cookie的共享。

easyXDM是一个实现了不同跨域字符串请求的开源框架,解决了各种浏览器的支持问题,它的简化版XDM正被Twitter使用,非常值得推荐。其核心对象是Socket和Rpc,区别在于是否为代理模式。

easyXDM.Socket

创建两个不同域名document的通讯通道。

easyXDM.Rpc

创建一个代理对象,在不同域名间传输数据。

内部的实现主要是根据浏览器的支持来判断和调用。

  • easyXDM.stack.SameOriginTransport 同域下的请求,一般可用来测试内部资源和外部资源的访问权限。
  • easyXDM.stack.FlashTransport Flash方式传播事件,原理是在浏览器中生成一个swf文件。
  • easyXDM.stack.PostMessageTransport 使用window.postMessage方式进行通讯。
  • easyXDM.stack.FrameElementTransport 通过向DOM插入frame的模式来触发事件。
  • easyXDM.stack.NameTransport 使用window.name来读取数据。
  • easyXDM.stack.HashTransport 最常见的方式,使用向DOM插入的iframe来进行通讯。
    easyXDM的主函数有onReady、onMessage和onDestory,分别对应初始化、发送消息和销毁几种场景。下面我们来看如何使用。

对easyXDM,我们需要为通讯的两端建立一个信息提供者(provider.html)和接收者(receiver.html),对提供者来说,不需要知道接收者的细节,只需要对事件作出响应,而接收者需要知道谁提供给它信息,并且广播出自己的状态。

provider.html

创建一个html文档,引入easyXDM.debug.js,在<body />中加入:

var socket = new easyXDM.Socket({
    onMessage: function(message, origin) {
        if (message == "open") {
            alert("Received '" + message + "' form '" + origin + "'");
        }
        socket.postMessage("Today is " + new Date().toGMTString());
    }
});
receiver.html 再创建一个html文档,同样需要引入easyXDM.dubug.js,在<body />中加入:
var socket = new easyXDM.Socket({
    remote: "http://www.domain1.com/easyXDM/provider.html",
    onMessage: function(message, origin) {
        alert("Received '" + message + "' from '" + origin + "'");
    },
    onReady: function() {
        socket.postMessage("open");
    }
});
测试时,可以修改本地hosts,就可以看到在不同域名之间的消息传递了。
127.0.0.1   www.domain1.com
127.0.0.1   www.domain2.com

跨域Cookie

如果不需要实时播放消息而是设置cookie,可以在provider的onMessage事件中写入cookie,由receiver事件来触发,经过测试是可行的。

var socket = new easyXDM.Socket({
    onMessage: function(message, origin) {
        if (message == "open") {
            document.cookie = "open=true";
            alert("Received '" + message + "' form '" + origin + "'");
        }
        socket.postMessage("Today is " + new Date().toGMTString());
    }
});
© 2018 Silent River All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero