Web客户端Js访问不同域中数据的解决方法

作者:马士华 发表于:2008-02-21 09:55 最后更新于:2008-07-30 14:30
版权声明:可以任意转载,转载时请务必以超链接形式标明文章 原始出处和作者信息。
http://www.hadoop.org.cn/web/jsonp/

 

Web客户端Js访问不同域中数据一直存在一些问题,比如A站点:a.com 要访问B站点:b.com的数据采用Ajax访问时会出现跨域的安全性问题,无法取得b.com的xml文档。好多项目都是采用在a.com写一个Proxy来代理访问b.com。流程图如下:

 

web client -> a.com -> b.com -> a.com ->web client

 

这种请求即费时间又浪费带宽,我们是不是可以修改上面的流程让客户端直接访问b.com呢?

 

web client -> b.com -> web client

 

所幸的是我们可以这么做。我们有一种数据表达方式叫 JSON.来处理远程登陆。这种格式可以 让Javascript不使用XMLHTTPRequest对象来获得数据,更有用的是我们可以取得不同域的数据抛开我们的Proxy。所要求的是 b.com增加一些数据传 输格式。我们更可以在服务端扩展JSON输出格式让Python和Ruby,C++,Php,Java,C#,Perl来读取数据.以便各种语言的客户端 能够获取数据。

什么是JSON

JSON(JavaScript Object Notation)是一个轻量级的数据交换格式。一种适合程序员阅读,适合机器处理的数据格式。JSON的表达式:

 

 
{"Result":{"item":[{"city":"beijing",age:32},{"city":"shanghai",age:20}]},Status:"china"};
 

上面的数据等同于XML的数据:

 

 
<xml>
<result>
<item>
<city>beijing</city>
<age>32</age>
</item>
<item>
<city>shanghai</city>
<age>20</age>
</item>
</result>
<status>china</status>
</xml>
 

大家可以看到JSON的格式数据传输量更少一些,因为这是Javascript的表达方法所以处理也更方便一些eval(jsonResponse)之后便可以访问了,比如:

 

 
var value ={
"Result":{
"item":[{"city":"beijing",age:32},{"city":"shanghai",age:20}]
},
Status:"china"
};
alert("city:"+ value.result.item[2].city +"/t age:"+ value.result.item[2].age );
 

远程脚本访问本地方法

 

在Javascript中跨域的脚本其实是能访问本地的函数的。例子:

 

 
 
<script language="javascript">
var hadoop= { callMethod:function(){ alert("This method is called by remote."); } }
</script>
<script language="javascript" src="http://www.hadoop.org.cn/code/jsonp/jsonp.call.js">
</script>
 

当调用上面脚本时,大家可以看到一个对话框包含一段文字:This method is called by remote.实例证明了远程脚本能够访问本地函数的。

合并概念调用调用远程数据

 

OK,联合上面的概念我们得知两个结论:

 

  • 1. 我们能够使用JSON的数据表达格式来提供查询数据。
  • 2. 远程的脚本是能够访问本地的函数。

只要我们告诉服务端我们的回调函数,服务端发回我们的脚本调用我们本地的回调函数我们就能取得跨域的远程的数据。服务端只要包含我们的回调函数:hadoop.callMethod({login:true,message:’登陆成功’});我们就能跨域取得数据。

下面是简单的例子:

Jsonp.html页面

 

 
 
<script src="http://www.hadoop.org.cn/wp-admin/jsonp.js" language="JavaScript" type="text/javascript">
</script>
 
<script language="JavaScript" type="text/javascript">
//request url
request = "http://www.hadoop.org.cn/code/jsonp/jsonp.php?";
 
//send user name and password
request +="user=testcallback&passwd=testtes";
 
//call jsonp
hadoop.jsonp({url:request,callback:function(json){ alert(json.user); } });
 
//now the message of box is testcallbac,because the sent parameter of user is testcallbac.
</script>
 

jsonp.js 的脚本:

 
/*
* jsonp - a simply remote data access
*
* author:josh ma
* email:beijing.josh@gmial.com
* Copyright (c) 2007 flashget.com
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* $Date: 2007-12-24 11:09 AM;
*
*/

(function(which){
 
var d = (new Date).getTime();
function p(s){
//translate callback function
var jsonp = "jsonp" + d++;
window[ jsonp ] = function(tmp){
s.callback(tmp);
// Garbage collect
window[ jsonp ] = undefined;
try{ delete window[ jsonp ]; } catch(e){}
}
//tell server the callback method
s.url = s.url + "&callback=" + jsonp;
 
//creat script
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = s.url;
//after script loaded,we remove the script
script.onload = script.onreadystatechange = function(){
if (!this.readyState || this.readyState == "loaded" ||
this.readyState == "complete") {
setTimeout(function(){
head.removeChild(script);
},50);
}
};
//insert script
head.appendChild(script);
}
 
//bind the inner method outside;
!which ? window["jsonp"] = p : which["jsonp"] = p;
})(hadoop={});
 

下载例子:jsonp.zip

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值