Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

JavaScript跨域与JSONP

  跨域问题的产生,最主要原因是COOKIE的安全问题。因为COOKIE是属于一个域的,如果允许跨域,客户端浏览器上储存的COOKIE就可以被它的所有者之外的程序访问到。举个例子吧,假如没有跨域问题,我现在就可以给百度发送个HTTP请求,获取你在百度上登录的用户名。或者获取SessionID,直接冒充你的帐号登录。为了避免这些问题,所以跨域访问的限制是非常有必要的。
  跨域行为通常只是用来给另一个域传递数据而已,对于这个简单的跨域要求很容易做到。在HTML中有着许多标签都是可以跨域访问的,比如IFRAME、IMG、SCRIPT,等。他们都可以跨域发送HTTP请求,所以如果只是单纯的发送而不需要接收数据,只要用任意一个可以发送跨域请求的HTML标签把数据放入URL中发送即可。但是有时候就是需要从另一个域获取数据,这时候通常使用SCRIPT标签,用JSONP的方式传递。这是正统,当然其它标签也不是不可以返回数据,比如IMG标签就可以返回图片的宽高,这也是一个数据,但是这些歪门邪道的方法不推荐使用。JSONP虽然不是正规协议,但是正在逐步迈向正规。至少目前jQuery就可以使用JSONP。
  跨域是一种正常行为,当你拥有许多个网站的时候,你可以实现在自己的网站之间传递数据。但是如果你想用“跨域”盗取其它网站的数据,那还是放弃吧。除非目标网站有给你提供JSONP的接口,或者有某些可以利用的漏洞,要不然真没什么办法实现。
  前面提到了JSONP,现在来说说JSONP到底是个啥。先来看个代码吧 //这是test.php的代码

//假如这个$obj是需要传递的对象
$obj=array('uid'=>1,'usn'=>'次碳酸钴');

//获取传入的函数名
$callback=$_GET['callback'];

//如果没传入就使用的默认函数名
if(!$callback)$callback='jsoncallback';

//输出一段JS格式的代码,调用用传入的函数名,参数为需要传递的$obj对象
echo $callback.'('.json_encode($obj).');';
//这段JS所在的文件是和test.php不同的域上的

//回调函数定义
function mycallback(obj){
  //输出传递过来的对象的usn属性
  alert(obj.usn);
};

window.onload=function(){
  //创建SCRIPT标签
  var script=document.createElement("script");
  //设置URL
  script.src="http://127.0.0.1:100/test.php?callback=mycallback";
  //把标签放入文档中以便生效
  document.body.appendChild(script);
};

  看到上面这个例子就应该明白了,JSONP实际上就是这样一个东西。传入一个回调函数的函数名称,服务器把需要传递的数据作为参数调用那个函数。上面的这个JS用jQuery写会非常简单。 $.getJSON(
  "http://127.0.0.1:100/test.php?callback=?",
  function(e){
    alert(e.usn);
  }
);
  这样就可以了,所以建议使用JSONP这个。如果不使用它也是可以传递数据的,只不过就没这么方便了,因为JS文件毕竟是死的,如果直接把数据放入全局变量中当然也可以传递,但是就浪费了一个全局变量。这就意味着很有可能和访问网站的JS中固有的全局变量冲突,JSONP就是解决了这个问题。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^