码迷,mamicode.com
首页 > Web开发 > 详细

你不知道的jQuery Item11 -- ajax jsonp跨域方法详解

时间:2016-07-19 10:47:33      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

文章从JSON和JSONP区别开始讲起,用实例来对比他们之间的不同之处,然后详细讲解了jQuery中的ajax jsonp的使用并给出了示例及详细参数说明。

1.JSON和JSONP

  JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于在浏览器和服务器之间交换信息。

  JSONP(JSON With Padding),就是打包在函数调用中的的JSON(或者包裹的JSON),你要跨域请求别人的东西,你肯定要包裹起来,不要污染了别人的东西,把Json数据包裹起来称为JSONP,个人理解,哈哈~~。

  JSON是一种数据格式,JSONP是一种数据调用方式。

 //JSON
 {
 “name”: “肖果平”
 }
 //JSONP
 callback({
 “name”: “小平果”
 })

  
出于安全考虑,脚本(AJAX)不能访问非本域的内容。但是,静态资源是不受域策略限制的,可以加载任意域的脚本、样式、图片等静态资源,JSOP就是利用这种原理来实现跨域获取数据的。

例1:

 //定义shoPrice函数,处理返回来的data数据
 function showPrice(data) {
     alert("Symbol: " + data.symbol + ", Price: " + data.price);
 }

代码如下:

 //在Web页面中包含showPrice函数和参数
 <script type="text/javascript">
 function showPrice(data) {
     alert("Symbol: " + data.symbol + ", Price: " + data.price);
 }
 </script>
 <script type="text/javascript">showPrice({symbol: ‘IBM‘, price: 91.42});</script>

  
本例展示了如何将静态JSON数据作为参数调用JavaScript函数。

例2:

  第一种的函数调用完全可以写在一个js文件中放在服务器上,用script标签加载到页面,而且这个标签可以动态地创建。

代码如下:

 <script type="text/javascript">

     function showPrice(data) {// This is our function to be called with JSON data
             alert("Symbol: " + data.symbol + ", Price: " + data.price);
 }

 var url = “remote.js”; // 外部脚本的URL
 // 动态插入脚本
 var script = document.createElement(‘script‘);
 script.setAttribute(‘src‘, url);

 // 加载script
 document.getElementsByTagName(‘head‘)[0].appendChild(script); 
 </script>

remote.js的内容和之前在标签里写的一样是:

showPrice({symbol: ‘IBM‘, price: 91.42}); 

  动态插入的JavaScript代码,将要传递的JSON数据作为参数,showPrice函数调用语句的参数。

  那么问题来了,每次获取到数据都调用showPrice函数吗?这就需要前后端程序猿做好约定,当然这样有很多不便,尤其是对于开放接口给公众开发的情况。JSOP这样处理:支持前端传递一个回调函数名参数,后端接收回调函数名参数,然后生成对该函数的调用,将JSON数据作为参数传递,在到达客户端时将其插入页面开始执行。

例3:

  动态插入代码,带有callback参数:

代码如下:

 <script type="text/javascript">
  // This is our function to be called with JSON data
  function showPrice(data) {
      alert("Symbol: " + data.symbol + ", Price: " + data.price);
  }
 var url = “remote.js?callback=‘showPrice‘”; // 外部脚本的URL
 // 动态插入脚本
 var script = document.createElement(‘script‘);
 script.setAttribute(‘src‘, url);
 // 加载script
 document.getElementsByTagName(‘head‘)[0].appendChild(script); 
  </script>

后端用PHP实现的JSONP服务的代码片段:

代码如下:

 $jsonData = getDataAsJson($_GET[‘symbol‘]);
 echo $_GET[‘callback‘] . ‘(‘ . $jsonData . ‘);‘;
 //这里接收到$_GET[‘callback‘] =showPrice;
 // 打印: showPrice({"symbol" : "IBM", "price" : "91.42"});

很好的契合了JSONP的定义,打包在函数调用中的JSON数据。

如果看晕了,就说简单一点!!!

浏览器是不允许直接跨域请求数据的,jsonp就是利用script标签可以跨域获取数据来工作的

步骤:

1.建一个函数,这个函数名(如此例中的jsonpCallback是要传给后端的)

<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">
  function jsonpCallback(result) {
    //alert(result);
    for(var i in result) {
      alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
    }
  }
  var JSONP=document.createElement("script");
  JSONP.type="text/javascript";
  JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";
  document.getElementsByTagName("head")[0].appendChild(JSONP);
</script>

2.新建一个script标签,src指向域名

3.将script插入body中

前端部分就是如此

————————————–

用jquery实现

  $.ajax({
      url: ‘http://10.95.192.27:8080/honeybee/zhuanti/export.action‘,
      dataType: "jsonp",
      jsonp: "topicsCallback",
      success: function(){}
  });

jsonp: 即与后端定好的名称。具体的处理函数在success里

2.在jQuery中使用JSONP

  AJAX和JSONP在jQuery中的调用方式看起来极为相像,千万不要被这种现象迷惑,它们本质上有很大不同。AJAX是通过XMLHttpRequest对象获取非页面内容,而JSONP是动态的添加

 $.ajax({
     url: "http://query.yahooapis.com/v1/public/yql",
     jsonpCallback: "showPrice",
     jsonp: "callback",
     // tell jQuery we‘re expecting JSONP
     dataType: "jsonp",
     data: {
         q: "select title,abstract,url from search.news where query=\"cat\"",
         format: "json"
     },
     // work with the response
     success: function( data ) {
         console.log( data ); // server response
     }
 });

ajax请求参数说明:
dataType String
预期服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如XML MIME类型就被识别为XML。在1.4中,JSON就会生成一个JavaScript对象,而script则会执行这个脚本。随后服务器端返回的数据会根据这个值解析后,传递给回调函数。可用值:

  • “xml”: 返回 XML 文档,可用 jQuery 处理。
  • “html”: 返回纯文本 HTML 信息;包含的script标签会在插入dom时执行。
  • “script”: 返回纯文本 JavaScript 代码。不会自动缓存结果。除非设置了”cache”参数。”’注意:”’在远程请求时(不在同一个域下),所有POST请求都将转为GET请求。(因为将使用DOM的script标签来加载)
  • “json”: 返回 JSON 数据 。
  • “jsonp”: JSONP 格式。使用 JSONP 形式调用函数时,如 “myurl?callback=?” jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。
  • “text”: 返回纯文本字符串

jsonp,

  重写jsonp请求中的回调函数的名称。用来替代“callback=?”这种GET或POST请求URL参数里的“callback”部分,例如{jsonp:‘onJsonPLoad‘}会导致“onJsonPLoad”传递给服务器。

jsonpCallback,

  为jsonp指定一个回调函数名。这个值将用来取代jQuery自动生成的随机函数名。这主要用来让jQuery生成度独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存GET请求的时候,指定这个回调函数名。但是实际使用过程中,并不用写回调函数,比如此例中的showPrice,不写也不会报错,因为jQuery在处理JSONP的时候,自动帮你生成回调函数并且把数据取出来共success方法调用。可能像这样:
代码如下:

 function success_jsonpCallback(data) { success(data); }  

以上就是本文的全部内容了,大家是否对jsonp有了细致的了解了呢。有什么疑问也请给我留言,大家共同探讨。

网上找到一个很好的例子,分享出来,很清楚的对比,自己动手测试了一番。

<html>
<head>
    <title>jQuery $.ajax jsonp</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Language" content="zh-CN" />
    <script type="text/javascript" src="http://files.cnblogs.com/Zjmainstay/jquery-1.6.2.min.js"></script>
</head>
<body>
<div id="myData"></div>
<script type="text/javascript">

/*
    当前文件为:http://www.test.com/index.html
*/

$(document).ready(function(){
    $.ajax({
        url:‘http://www.wp.com/getData.php‘,       //跨域到http://www.wp.com,另,http://test.com也算跨域
        type:‘GET‘,                                //jsonp 类型下只能使用GET,不能用POST,这里不写默认为GET
        dataType:‘jsonp‘,                          //指定为jsonp类型
        data:{"name":"Zjmainstay"},                //数据参数
        jsonp:‘callback‘,                          //服务器端获取回调函数名的key,对应后台有$_GET[‘callback‘]=‘getName‘;callback是默认值
        jsonpCallback:‘getName‘,                   //回调函数名
        success:function(result){                  //成功执行处理,对应后台返回的getName(data)方法。
            $("#myData").html(‘1、My name is ‘+result.name+‘.I\‘m ‘+result.age+‘ years old.<br />‘);
        },
        error:function(msg){
            alert(msg.toSource());                 //执行错误
        }
    }); 

    /* 这里不是跨域 */
    $.ajax({
        url:‘http://www.test.com/getData.php‘,       //正常
        // url:‘http://test.com/getData.php‘,        //跨域到http://test.com
        type:‘GET‘,                    //这里是普通ajax,可以用POST
        dataType:‘json‘,
        data:{"name":"Zjmainstay"},
        success:function(result){
            $("#myData").append(‘2、My name is ‘+result.name+‘.I\‘m ‘+result.age+‘ years old.‘);
        },
        error:function(msg){
            alert(msg.toSource());                //跨域错误会执行到这里
        }
    });
});
</script>
</body>
</html>

文件:http://www.wp.com/getData.php

<?php
    $data = array(
        "name"=>$_GET[‘name‘],
        "age"=>23,
    );
    echo $_GET[‘callback‘]."(".json_encode($data).")";        //等价:echo ‘getName({"name":"Zjmainstay","age":23})‘;
?>

文件:http://www.test.com/getData.php(不跨域),同样是http://test.com/getData.php(跨域)

<?php
    $data = array(
        "name"=>$_GET[‘name‘],
        "age"=>23,
    );
    echo json_encode($data);
?>

你不知道的jQuery Item11 -- ajax jsonp跨域方法详解

标签:

原文地址:http://blog.csdn.net/i10630226/article/details/51934751

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!