以前写过一片post是讲js跨站点通讯的,自觉似乎没有整理清楚,接下来重新整理一下。
javascript 使用xmlhttp对象无法cross domain进行请求已经成了尝试,可是很多时候还是需要跨站点进行数据传输。比如google personal homepage的widget可以放在任意的外部站点上正常工作,看似神奇,其实也就是利用了ajax patterns 里面将的一种叫做 script ondemand的技术实现的,使用这种技术进行跨站点通讯的核心原理是:
- http://a.com/a.html中的javascript向当前页面的<head>标记里面写入一个<script>标记,这个标记的src属性指向需要进行数据请求的http://b.com/data.php页面,于是浏览器便会向该地址发送加载脚本的请求
- 此时b.com的data.php页面就返回一段包含了客户端js回调函数与返回数据的脚本,让该脚本执行原先在a.com的a.html种事先写好的回调函数,并将数据传给该函数
客户端javascript代码如下:
XSSRequest = {
stack_callback : {},
request : function(url,callback){
var cid = this._generateGuid();
var func_cb = callback || function(){};
url += ( url.match(/?/) ? '&' : '?')
+ 'requestId=' + cid
+ '&callback=XSSRequest.response;
var stackObj_cb = {};
stackObj_cb.requestId = cid;
stackObj_cb.function_callback = func_cb;
stackObj_cb.url = url;
this.stack_callback[cid] = stackObj_cb;
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = url;
document.getElementsByTagName('head')[0].appendChild(s);
},
response : function(requestId,responseObj){
if(this.stack_callback[requestId]){
(this.stack_callback[requestId].function_callback)(responseObj);
delete this.stack_callback[requestId];
}
},
_generateGuid : function(){
var hex =
new Array(
'0','1','2','3','4','5','6','7','8',
'9','a','b','c','d','e','f');
var outB = '{';
for (count = 0; count < 32; count++){
if ((count == 8) || (count == 12) || (count == 16) || (count == 20))
outB += '-';
outB += hex[ Math.floor(Math.random() * 16)];
}
return outB.toUpperCase() + '}';
}
}
当调用XSSRequest.request(url,function(responseObj){})方法是,会产生一个形如http://b.com/data.php?requestId=xx-xx-xx&callback=XSSRequest.response的请求,之后服务器应该返回的字符串如下:
XSSRequest.response(’xx-xx-xx’,{});
后一个{}是返回数据的JSON对象。
如此一来,一个通用的cross domain 通讯框架就建立起来了,其次就是服务器端的支持了,这种简单的字符串输出相信任何一种语言都能胜任,不再赘述。
同时,大家可以比较一下,我构建的这个跨域通讯方案与这篇文档的方案哪个比较方便使用。