ajax 和 jsonp 区别如下:
jquery、ext、dojo 这类库的实现手段其实大同小异,在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但 img、iframe、script 等标签是个例外,这些标签可以通过 src 属性请求到其他服务器上的数据。利用 script 标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。一般的 ajax 是不能跨域请求的,因此需要使用一种特别的方式来实现跨域,其中的原理是利用 <script> 元素的这个开放策略。
这里有2个重要的参数:
jsonpCallback:
为 jsonp 请求指定一个回调函数名。这个值将用来取代 jQuery 自动生成的随机函数名。这主要用来让 jQuery 生成一个独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存 GET 请求的时候,指定这个回调函数名。从jQuery 1.5 开始,你也可以使用一个函数作为该参数设置,在这种情况下,该函数的返回值就是 jsonpCallback 的结果。
jsonp:
在一个 jsonp 请求中重写回调函数的名字。这个值用来替代在 "callback=?" 这种 GET 或 POST 请求中 URL 参数里的 "callback" 部分,比如 {jsonp:'onJsonPLoad'} 会导致将 "onJsonPLoad=?" 传给服务器。在 jQuery 1.5,设置 jsonp 选项为 false,阻止了 jQuery 从加入 "?callback" 字符串的 URL 或试图使用 "=?" 转换。在这种情况下,你也应该明确设置 jsonpCallback 设置。例如, { jsonp: false, jsonpCallback: "callbackName" }。
当我们正常地请求一个 JSON 数据的时候,服务端返回的是一串 JSON 类型的数据,而我们使用 JSONP 模式来请求数据的时候,服务端返回的是一段可执行的 JavaScript 代码,所以我们可见服务器代码最后一行。
$_GET['callback']).'('. json_encode(array('status'=>1,'info'=>'OK')) .')
就是执行的 backfunc 方法,然后把数据通过回调的方式传递过。
OK,就是整个流程就是:
客户端发送一个请求,规定一个可执行的函数名(这里就是 jQuery 做了封装的处理,自动帮你生成回调函数并把数据取出来供 success 属性方法来调用,不是传递的一个回调句柄),服务端接受了这个 backfunc 函数名,然后把数据通过实参的形式发送出去
右边伪代码模拟了下 jsonp 的原理。
<!doctype html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <script src="http://code.jquery.com/jquery-latest.js"></script> <title></title> </head> <body> <script type="text/javascript"> ////////////////////////////////// // jQuery的调用 ////////////////////////////////// $.ajax({ crossDomain :true, url: 'http://192.168.1.113:8080/github/jQuery/jsonp.php', //不同的域 type: 'GET', // jsonp模式只有GET是合法的 data: { 'action': 'aaron' }, // 预传参的数组 dataType: 'jsonp', // 数据类型 jsonp: 'callback', // 指定回调函数名,与服务器端接收的一致,并回传回来 jsonpCallback:"flightHandler", success: function(json) { console.log(json); } }) ////////////////////////////////// // jsonp的原理 ////////////////////////////////// //服务器调用的全局函数,用来接受数据 function flightHandler(data){ console.log(data) } function createJsonp(url, complete) { var script = jQuery("<script>").prop({ async: true, src: "http://192.168.1.113:8080/github/jQuery/jsonp.php?callback=flightHandler&action=aaron&_=1418782732584" }).on( "load error", callback = function(evt) { script.remove(); callback = null; } ); document.head.appendChild(script[0]); } createJsonp() ////////////////////////////////// // PHP端代码 ////////////////////////////////// // <?php // header('Content-Type:text/json;charset=utf-8'); // echo trim( $_GET['callback']).'('. json_encode(array('status'=>1,'info'=>'OK')) .')'; // ?> </script> </body> </html>