6-9 jsonp的原理
本节编程练习不计算学习进度,请电脑登录imooc.com操作

jsonp的原理

 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 的原理。

 

任务

  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
  5. <script src="http://code.jquery.com/jquery-latest.js"></script>
  6. <title></title>
  7. </head>
  8. <body>
  9.  
  10.  
  11. <script type="text/javascript">
  12.  
  13.  
  14. //////////////////////////////////
  15. // jQuery的调用
  16. //////////////////////////////////
  17. $.ajax({
  18. crossDomain :true,
  19. url: 'http://192.168.1.113:8080/github/jQuery/jsonp.php', //不同的域
  20. type: 'GET', // jsonp模式只有GET是合法的
  21. data: {
  22. 'action': 'aaron'
  23. }, // 预传参的数组
  24. dataType: 'jsonp', // 数据类型
  25. jsonp: 'callback', // 指定回调函数名,与服务器端接收的一致,并回传回来
  26. jsonpCallback:"flightHandler",
  27. success: function(json) {
  28. console.log(json);
  29. }
  30. })
  31.  
  32.  
  33. //////////////////////////////////
  34. // jsonp的原理
  35. //////////////////////////////////
  36. //服务器调用的全局函数,用来接受数据
  37. function flightHandler(data){
  38. console.log(data)
  39. }
  40.  
  41. function createJsonp(url, complete) {
  42. var script = jQuery("<script>").prop({
  43. async: true,
  44. src: "http://192.168.1.113:8080/github/jQuery/jsonp.php?callback=flightHandler&amp;action=aaron&amp;_=1418782732584"
  45. }).on(
  46. "load error",
  47. callback = function(evt) {
  48. script.remove();
  49. callback = null;
  50. }
  51. );
  52. document.head.appendChild(script[0]);
  53. }
  54.  
  55. createJsonp()
  56.  
  57.  
  58.  
  59. //////////////////////////////////
  60. // PHP端代码
  61. //////////////////////////////////
  62. // <?php
  63. // header('Content-Type:text/json;charset=utf-8');
  64. // echo trim( $_GET['callback']).'('. json_encode(array('status'=>1,'info'=>'OK')) .')';
  65. // ?>
  66.  
  67. </script>
  68. </body>
  69. </html>
下一节