下午写代码的时候遇到一个跨域传输的问题,隔壁dojo组的帅哥建议我用dojox.io.windowName,于是我打算找点资料看看,结果搜了下发现几乎没有相关资料,连dojoCampus 上都没有详细解释。没办法,dojo的文档确实不多。我只好找篇英文的凑活看看了。
原文链接:http://www.sitepen.com/blog/2008/07/22/windowname-transport/
译:
window.name传输是一种可以进行跨域浏览器数据交互的新技术,同时它还能够同未知来源建立起安全的混搭 。dojo将window.name实现在了dojox.io.windowName 模块中,利用
window.name机制,我们将很容易建立起web服务。
windows.name是通过在iframe中载入一个跨域的HTML文件来工作的。随后,HTML文件将窗体的window.name属性设置为返回的响应数据。请求方可以取得window.name的值来获取响应数据,而被请求的资源从来没能够访问过请求者的执行环境(比如js变量,DOM树,cookie)。
Dojo API
为了使用window.name传输,你可以使用dojox.io.windowName 中唯一一个函数:send,它有着与
dojo.xhr 非常类似的接口。
dojox.io.windowName.send(method, args);
其中,参数method可以是GET或者POST。参数args是一个对象,该对象包含了目标URL以及其他所有Dojo ioArgs API 的信息。当你调用dojox.io.windowName.send 时,它会发送指定的请求,然后返回一个dojo.Deferred 对象,用以监听最后的响应。例如:
var deferred = dojox.io.windowName.send ( "GET", { url:"http://somesite.com/resource" } ); deferred.addCallback( function(result){ alert("The request returned " + result); } );
Making Web Services Available with window.name
为了用window.name实现web服务,服务器应该仅仅寻找那些包含一个windowname 参数的请求。如果请求中包含了windowname 参数,服务器需要构造一个HTML文本,并且将window.name设置成返回给客户端的内容。举例来说,一个客户端发送如下的请求:
假设服务器端的响应为“Hello”,那么它应该返回给客户端一个HTML页面:
<html>
<script type="text/javascript">
window.name="Hello";
</script>
</html>
这样,客户端接收到的值就是“Hello”.同样,我们可以轻松的解析JSON格式的数据:
<html>
<script type="text/javascript">
window.name=’{"foo":"bar"}’;
</script>
</html>
客户端会接收到这段代表JSON的字符串‘{"foo":"bar"}’,利用类似dojo.fromJson 之类的JSON解释器,这种字符串很容易被翻译为JSON对象。我们强烈建议你在编写客户端的时候采用JSON或者更加安全的JS验证器,如果你不想让那些糟糕的代码肆无忌惮的访问web服务的数据。为了更加安全的解析JSON,你可以在调用dojo.fromJson 之前先用dojox.secure.capability 对JSON进行测试:
var deferred = dojox.io.windowName.send("GET", {url:"http://somesite.com/resource"}); deferred.addCallback(function(result){ // capability.validate will throw an error // if there is unsafe script code in the JSON dojox.secure.capability.validate(result,[],{}); console.log("received object", dojo.fromJson(result)); });
在字符串中手动编写那种很大的JSON对象可能很麻烦,并且容易出错。你可以使用HTML模板来解决这个问题。HTML模板使得编写JSON数据更轻松,并且会被当成一个JSON字符串来传输,而不需要你手动去分解出JSON对象。
<html>
<script type="\’text/javascript\’">
window.name = document.getElementsByTagName("script")[0]
.innerHTML.match(/temp\s*=([\w\W]*)/)[1];
temp= {foo:"bar", baz:"foo"}// put json data here
</script>
</html>
同样,如果你想要传输一份HTML或者XML数据而又不想将他们都写到一个字符串中,这边有一份模板:
<html>
<body>
<p id="content">
some <strong>html/xml-style</strong>data
</p>
</body>
<script type="\’text/javascript\’">
window.name = document.getElementById("content").innerHTML;
</script>
</html>
这个模板已经在FF2,FF3,Safari3,IE6,IE7,Opera9下被测试过了。你可以看一个使用了window.name机制的简单demo页面 。默认情况下,这个例子会从我们的Persevere 服务器加加载数据。