JSONP原理及实现

跨域实现的两种方式
一、通过src="http://romateServer.com/api?callback=callbackHandler"
回调成功后,在浏览器端实现callbackHandler方法,返回值在callbackHandler参数中
批注:既然如此,所有src都可以实现跨域。比如图片src等。具体实现是将该内容动态的插入到DOM中。

二、通过jQuery的ajax参数{dataType:jsonp,jsonp:callback,success:function(){}}
回调成功后,返回值在success参数中
在jQuery1.5后,又增加如下描述,照着做之后发现报错:
Uncaught SyntaxError: Unexpected token :
暂未找到解决办法,所以还是回归传统方式。
jsonp
Type: String
Override the callback function name in a JSONP request. This value will be used instead of 'callback' in the 'callback=?' part of the query string in the url. So {jsonp:'onJSONPLoad'} would result in 'onJSONPLoad=?' passed to the server. As of jQuery 1.5,setting the jsonp option to false prevents jQuery from adding the "?callback" string to the URL or attempting to use "=?" for transformation. In this case,you should also explicitly set the jsonpCallback setting. For example,{ jsonp: false,jsonpCallback: "callbackName" }
jsonpCallback
Type: String or Function()
Specify the callback function name for a JSONP request. This value will be used instead of the random name automatically generated by jQuery. It is preferable to let jQuery generate a unique name as it'll make it easier to manage the requests and provide callbacks and error handling. You may want to specify the callback when you want to enable better browser caching of GET requests. As of jQuery 1.5,you can also use a function for this setting,in which case the value of jsonpCallback is set to the return value of that function.
ajax与jsonp的异同再做一些补充说明: 1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;
2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。
3、所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。
4、还有就是,jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。
总而言之,jsonp不是ajax的一个特例,哪怕jquery等巨头把jsonp封装进了ajax,也不能改变这一点!
2014-06-09
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。
JSONP原理: 首先在客户端注册一个callback,然后把callback的名字传给服务器。
此时,服务器先生成 json 数据。
然后以 javascript 语法的方式,生成一个function,function 名字就是传递上来的参数 jsonp.
最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)
实例: (1)客户端:(任一)
Html代码
  1. <metacontent="text/html;charset=utf-8"http-equiv="Content-Type"/>
  2. scripttype="text/javascript">
  3. functionjsonpCallback(result){
  4. //alert(result);
  5. for(variinresult){
  6. alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
  7. }
  8. varJSONP=document.createElement("script");
  9. JSONP.type="text/javascript";
  10. JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";
  11. document.getElementsByTagName("head")[0].appendChild(JSONP);
  12. </script>


alert(result.a);
  • alert(result.b);
  • alert(result.c);
  • scripttype="text/javascript"src="http://crossdomain.com/services.php?callback=jsonpCallback">注意:JavaScript的链接,必须在function的下面。
    (2)服务器端:
    Php代码
      <?php
    1. //服务端返回JSON数据
    2. $arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
    3. $result=json_encode($arr);
    4. //echo$_GET['callback'].'("Hello,World!")';
    5. //echo$_GET['callback']."($result)";
    6. //动态执行回调函数
    7. $callback=$_GET['callback'];
    8. echo$callback."($result)";

  • jQuery中的实现 如果将上述JS客户端代码用jQuery的方法来实现,也非常简单。
    $.getJSON
    $.ajax
    $.get
    (1)$.getJSON

    (2)$.ajax
    $.ajax({
  • url:"http://crossdomain.com/services.php",250)"> dataType:'jsonp',250)"> data:'',250)"> jsonp:'callback',0); padding:0px; margin:0px; width:auto; border:0px">//jsonpCallback:"flightHandler",//可选,jQuery把返回放到success里了。默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
  • success: },250)"> timeout:3000
  • (3)$.get
    $.get('http://crossdomain.com/services.php?callback=?',{
  • name:encodeURIComponent('tester')
  • function(json){
  • injson)alert(i+":"+json[i]);
  • 'jsonp');
  • 其中 jsonCallback 是客户端注册的,获取跨域服务器上的json数据后,回调的函数。
    http://crossdomain.com/services.php?callback=jsonpCallback
    这个 url 是跨域服务 器取 json 数据的接口,参数为回调函数的名字,返回的格式为
    jsonpCallback({msg:'this is json data'})
    使用JSON的优点在于: 比XML轻了很多,没有那么多冗余的东西。
    JSON也是具有很好的可读性的,但是通常返回的都是压缩过后的。不像XML这样的浏览器可以直接显示,浏览器对于JSON的格式化的显示就需要借助一些插件了。
    在JavaScript中处理JSON很简单。
    其他语言例如PHP对于JSON的支持也不错。
    JSON也有一些劣势:
    JSON在服务端语言的支持不像XML那么广泛,不过JSON.org上提供很多语言的库。
    如果你使用eval()来解析的话,会容易出现安全问题。
    尽管如此,JSON的优点还是很明显的。他是Ajax数据交互的很理想的数据格式。
    缺点与不足: JSONP 是构建 mashup 的强大技术,但不幸的是,它并不是所有跨域通信需求的万灵药。它有一些缺陷,在提交开发资源之前必须认真考虑它们。
    第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到 404 错误,也不能取消或重新开始请求。不过,等待一段时间还没有响应的话,就不用理它了。(未来的 jQuery 版本可能有终止 JSONP 请求的特性)。
    JSONP 的另一个主要缺陷是被不信任的服务使用时会很危险。因为 JSONP 服务返回打包在函数调用中的 JSON 响应,而函数调用是由浏览器执行的,这使宿主 Web 应用程序更容易受到各类攻击。如果打算使用 JSONP 服务,了解它能造成的威胁非常重要。
  • 相关文章

    文章浏览阅读2.4k次。最近要优化cesium里的热力图效果,浏览...
    文章浏览阅读1.2w次,点赞3次,收藏19次。在 Python中读取 j...
    文章浏览阅读1.4k次。首字母缩略词 API 代表应用程序编程接口...
    文章浏览阅读802次,点赞10次,收藏10次。解决一个JSON反序列...
    文章浏览阅读882次。Unity Json和Xml的序列化和反序列化_uni...