原文:http://www.cssdemon.me/?p=298
在web2.0的时代,ajax的盛行给web带来了翻天覆地的变化,允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索。使用XMLHttpRequest
函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器。不过,由于受到浏览器的限制,该方法不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。
在工作中,我们经常会碰到跨域的问题,同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。实现跨域的方式有很多,如:使用iframe隐藏,JSONP等。
现在主流的都是使用JSONP去实现跨域,什么是JSONP?简单的来说就是JSON-Padding。
对很多新手来说JSONP并不是很理解,简单的说明下:
<script src=“http://jsonp.js”> </script>
而jsonp.js里面有一段JS代码,浏览器会执行里面的代码。想到这个,前端页面我们可以写一个函数,如:
- functionjsonp(data){
- alert(data.name);
- }
data为json格式的数据,然后再远程的jsonp.js里面,有一段代码为jsonp({“name”:”Demon”,”age”:”23”}),浏览器会根据这段代码执行函数,从而弹出”Demon”。
如何使用JSONP,使用JSONP,我们必须带一个参数传给程序员,在后面加一个callback=?的参数,“?”为前端页面JS函数的名称,如果不是使用JQ库的,这个需要根据前端工作人员来定义。如果使用JQ库,那么这里比较方便了,JQ库会直接把返回过来的”?”进行解析,如图所示:
红色圈圈部分就是JQ自动解析成的函数名,然后执行。JQ实现JSONP方法很简单,代码如下:
- $.ajax({
- type:"GET",
- url:"http://xxx.PHP?action=add&callback=?",
- dataType:"json",108); line-height:14px"> success:function(msg){
- console.log(msg.status);
- 或者:
url:"http://xxx.PHP?action=add",248); line-height:14px"> dataType:"jsonp",255)">这里注意下,如果url中带了”callback=?”,那么dataType只要写json就可以,如果dataType为jsonp,那么url的链接可以不带”callback=?”,JQ会自动在链接中加上”callback=?”
程序接口如何实现:
注意的是这里程序需要配合,程序返回数据的时候,必须带上url中callback的参数,比如PHP中返回要写成 echo $_GET[‘callback’] . ’(’ . josn_encode($josnData) . ’)’;
JSONP虽然强大,但是也有一些缺陷:
第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到 404 错误,也不能取消或重新开始请求。在安全方面,如果不是信任的网站提供的接口,很有可能会受到恶意的攻击。等等。
这里提供几个JSONP的程序接口,大家可以在自己电脑试试:
来自 Digg 的头条新闻:http://services.digg.com/stories/top?appkey=http%3A%2F%2Fmashup.com&type=javascript
&callback=?邮编的位置信息:http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?
来自 Flickr 的最新猫图片:http://api.flickr.com/services/Feeds/photos_public.gne?tags=cat&tagmode=any
&format=json&jsoncallback=?在邮编为 10504 的地区搜索比萨:http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza &zip=10504&results=2&output=json&callback=?