对jQuery ajax jsonp的理解和使用实例

目前主流的前端跨域请求方式有两种,一种是XHR2 CORS,也就是在服务端填上响应头:
header(“Access-Control-Allow-Origin:*”);
/星号表示所有的域都可以接受,/
header(“Access-Control-Allow-Methods:GET,POST”);

CORS不支持ie10以下。但是

第二种是更加方便的就是jsop了,jsop有很多种实现方式,除了原生的 js script jsop之外,其他支持jsop的框架也都能完成。我今天主要就是讲一讲自己在使用jquery jsop时碰到的坑以及jquery ajax和jquery jsop 的区别。

首先请看我的demo:

//ajax方法
function total_tendency() {
      $.ajax({
          url: "/count/storage/data?callback=storageSurvey",
          dataType: "jsonp",  //指定服务器返回的数据类型为jsonp
          type: "GET", 
          async:true,  
          jsonp: "callback", ///指定参数名称,默认为callback  
          jsonpCallback:"storageSurvey", //指定回调函数名称
          success: function (data) {
                   storageSurvey_local(data);
          },
          error:function () {
            alert("error");
    }
}


function storageSurvey_local(data) {
    //将后台返回的数据先进行base64解码,再转换成json格式。
    function decode(rtnData){
                  var dstr = kvcommon.base64Decode(rtnData);
                  var rtnData = kvcommon.Ajax.Str2Json(dstr);
                  return rtnData;
              }
              var now_data = decode(data);
              var json = now_data[0];
              console.log(now_data);
              if(json.status == 0) {
                   var length = json.len;
                     modules = {};
                  //数据渲染
                   var modules = json.storage;
                  var max_count = json.max_count;
                  //在model_add()这个方法里进行数据获取和渲染
                   model_add(length,modules,max_count);

              }
}

在total_tendency( )这个函数里的ajax中我使用的ajax里可以看到,所有加了注释的地方都是与普通ajax传json数据不一样的地方。
只有这些不同吗?当然不是的,网上很多都说ajax和jsop不能归结为一种东西,事实上也正是如此,为什么这么说?请看如下代码:

//ajax方法
function total_tendency() {
      $.ajax({
          url: "/count/storage/data?callback=storageSurvey",
          dataType: "jsonp",  //指定服务器返回的数据类型为jsonp
          type: "GET", 
          async:true,  
          jsonp: "callback", ///指定参数名称,默认为callback  
          jsonpCallback:"storageSurvey", //指定回调函数名称
          success: function (data) {
                  //把success里调用的函数改为回调函数名。
                   storageSurvey(data);
          },
          error:function () {
            alert("error");
   }
}


function storageSurvey(data) {
    // 调用次数测试
    alert("test");

    //将后台返回的数据先进行base64解码,再转换成json格式。
    function decode(rtnData){
                  var dstr = kvcommon.base64Decode(rtnData);
                  var rtnData = kvcommon.Ajax.Str2Json(dstr);
                  return rtnData;
              }
              var now_data = decode(data);
              var json = now_data[0];
              console.log(now_data);
              if(json.status == 0) {
                   var length = json.len;
                     modules = {};
                  //数据渲染
                   var modules = json.storage;
                  var max_count = json.max_count;
                  //在model_add()这个方法里进行数据获取和渲染
                   model_add(length,modules,max_count);

              }
}

再将ajax success中调用的函数名改为回调函数名后,在此函数中加入一个alert(“test”),执行后发现test弹出了两次。也就是说storageSurvey( )这个函数执行了两次。再看下面这这段代码:

//ajax方法
function total_tendency() {
      $.ajax({
          url: "/count/storage/data?callback=storageSurvey",
          dataType: "jsonp",  //指定服务器返回的数据类型为jsonp
          type: "GET", 
          async:true,  
          jsonp: "callback", ///指定参数名称,默认为callback  
          jsonpCallback:"storageSurvey", //指定调用的回调函数名称
          /* success: function (data) {
                  //把success里调用的函数改为回调函数名。
                   storageSurvey(data);
          },
          error:function () {
            alert("error");
  }*/
}

function storageSurvey(data) {
    // 调用次数测试
    alert("test");

    //将后台返回的数据先进行base64解码,再转换成json格式。
    function decode(rtnData){
                  var dstr = kvcommon.base64Decode(rtnData);
                  var rtnData = kvcommon.Ajax.Str2Json(dstr);
                  return rtnData;
              }
              var now_data = decode(data);
              var json = now_data[0];
              console.log(now_data);
              if(json.status == 0) {
                   var length = json.len;
                     modules = {};
                  //数据渲染
                   var modules = json.storage;
                  var max_count = json.max_count;
                  //在model_add()这个方法里进行数据获取和渲染
                   model_add(length,modules,max_count); 
              }
}

将success和error屏蔽,执行代码,有意思的是test还会弹出来,不过只弹出来了一次,意味着storageSurvey( )这个函数这次只执行了一次
看出jsop与ajax的区别了吗?如果是ajax,你把在success中调用的函数屏蔽掉,它还会执行吗?显然不会!那么在jsop中为什么会执行呢?原因就是这句话:
jsonpCallback:”storageSurvey”,
这句属性的设置。它本意是设置请求url中callback=后面那个回调函数的名称,但有意思的是,如果你在此ajax函数外的js中重写了这么一个函数,ajax就会直接调用此函数。jquery jsop的这个功能应该是基于原生的js调用jsop的方法,而原生js实现jsonp跨域也更能让大家理解jsonp实现跨域的原理。看下面这段代码:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript">
    function connect_data(data){
        alert("age:" + data.age + "name:" + data.name);
    }
</script>
<script type="text/javascript" src="jquery-1.8.3.min.js">
</script>
<script type="text/javascript" src="这里写服务器端调用此函数的文件路径"></script>
</body>
</html>

然后只需在服务器端以connect_data( ) 命名的函数中返回json数据即可,如有需要,也可自行选择加密方式,就如我在一开始的demo中用的就是base64decode。

从上面的这个demo中可以看出,jsonp的跨域原理就是利用了src可以避开同源策略这一特性,在原生js中需要手动包裹一层script,在src里放请求路径,在路径里的文件中传输jsop数据。而jquery jsonp则自动动态的给你包裹了一层script标签和src属性。

补充:

这是百度百科对同源策略的描述:

猜你喜欢

转载自blog.csdn.net/dk2290/article/details/78857632