jQuery中的Ajax(全)

  内容很繁杂,长话短说。关于Ajax的介绍在这儿

导读  

  jQuery 对 Ajax 做了大量的封装,我们使用起来也较为方便,不需要去考虑浏览器兼容性。对于封装的方式,jQuery 采用了三层封装:最底层的封装方法为:$.ajax(),而通过这层封装了第二层有三种方法:.load()$.get()$.post(),最高层是$.getScript()$.getJSON()方法。

load()

  $element.load( url [, data ] [, complete ] )。data可以是 “String” 或 “Object” 。load()是以post方式请求的。

  • $( 'body' ).load( 'abc.php .selector' );
  • $( 'body' ).load( 'abc.php?name=real&age=20' );
  • $( 'body' ).load( 'abc.php', 'name=real&age=20' );
  • $( 'body' ).load( 'abc.php', { name:'real', age:20 } );
  • $( 'body' ).load( 'abc.php', { name:'real', age:20 }, function ( data ) {} );

get()和post()

  $.get( url [, data ] [, success ] [, dataType ] )
  $.post( url [, data ] [, success ] [, dataType ] )
  
  第四参数 type 是指定异步返回的类型。一般情况下 type 参数是智能判断,并不
需要我们主动设置,如果主动设置,则会强行按照指定类型格式返回。

  如果载入的是 xml 文件,type 会智能判断。如果强行设置 html 类型返回,则会
把 xml 文件当成普通数据全部返回,而不会按照 xml 格式解析数据。

  关于get和post的区别这里就不说了。在这里写过

getScript()和getJSON()

  $.getScript( url [, success ] )
  $.getJSON( url [, data ] [, success ] )
  jQuery 提供了一组用于特定异步加载的方法:$.getScript(),用于加载特定的 JS 文件;
$.getJSON(),用于专门加载 JSON 文件。

  有时我们希望能够特定的情况再加载 JS 文件,而不是一开始把所有 JS 文件都加载了,
这时可以使用$.getScript()方法。

ajax()

$.ajaxSetup( options )

  有时,我们可能会在同一个程序中多次调用$.ajax()方法。而它们很多参数都相同,这个时候我们课时使用 jQuery 提供的$.ajaxSetup()请求默认值来初始化参数。即使设置了$.ajaxSetup,但它仍可以被$.ajax覆盖。

$.ajaxSetup({
  type : 'POST'
});

  
  $.ajax( url [, settings ] )
  $.ajax( [settings ] )(常用)
  $.ajax()是所有 ajax 方法中最底层的方法,所有其他方法都是基于$.ajax()方法的封装。
与上述方法不同的是,上述基于ajax封装的方法并没有提供错误回调函数。更具体的在[jQuery官方api]。(http://api.jquery.com/jQuery.ajax/)
这里写图片描述

$.ajaxStart( function () {
    $( '.loading' ).show();
})
$.ajaxStop( function () {
    $( '.loading' ).hide();
})
$.ajax({
    type: 'get',
    url: 'some.php',
    data: $('#someForm').serizlize(),
    success: function ( data ) {}
    timeout: 15000,
    error: function ( data ) {}
})

序列化

  对于表单,我们更喜欢直接用序列化来发送数据。因为这样很方便。
  
  .serialize()方法不但可以序列化表单内的元素,还可以直接获取单选框、复选框和下拉
列表框等内容。

  除了.serialize()方法,还有一个可以返回 JSON 数据的方法:.serializeArray()。这个方法
可以直接把数据整合成键值对的 JSON 对象。

  在使用 data 属性传递的时候,如果是以对象形式传递键值对,可以使用$.param()方法将对象转换为字符串键值对格式。使用$.param()将对象形式的键值对转为 URL 地址的字符串键值对,可以更加稳定准确的传递表单内容。因为有时程序对于复杂的序列化解析能力有限,所以直接传递 obj对象要谨慎。
  比如console.log($.param({a:1,b:2}));// a=1&b=2
  
  如下是一张序列化的表单数据:
  

<body>
    <form action="">
        账户名:<input type="text" name="username"/>
        密码:<input type="password" name="password"/>
        电子邮箱: <input type="email" name="email"/>
        性别: 
          <input type="radio" name="sex" value="male"/><input type="radio" name="sex" value="female"/>女
        爱好:
        <input type="checkbox" name="basketball" value="basketbal"/>篮球
        <input type="checkbox" name="football" value="football"/>足球
        省份:
         <select name="province" id="">
           <option value="0">安徽</option>
           <option value="1">重庆</option>
           <option value="2">四川</option>
         </select>
         <button>提交</button>
    </form>

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
  $('button').click( function( e ) {
    e.preventDefault();
    console.log($('form').serialize());
    console.log($('form').serializeArray());
  })
</script>
</body>

上面是直接序列化,下面是序列化为数组。前者是String类型,后者是Object类型
这里写图片描述

全局事件

  在ajax请求中有个global属性,默认是true,表示可以使用全局事件,如果设置为false,那么下列这些函数将对这个ajax请求不起作用。
  $( document ).ajaxStart( handler ):请求开始执行。
  $( document ).ajaxStop( handler ):请求结束执行。
  $( document ).ajaxSend( handler ):在Ajax请求发送前执行。
  $( document ).ajaxError( handler ):请求出错执行。
  $( document ).ajaxSuccess( handler ):请求成功,对数据处理后执行。
  $( document ).ajaxComplete( handler ):请求完成 执行,不管成功失败。
  这些全局事件与$.ajax中的事件是一样的,不过它是针对所有ajax请求的。
  以上代码在 jQuery1.8 及以后的版本不在有效,需要使用 jquery-migrate 向下兼容才能运行。新版本中,必须绑定在 document 元素上。

jsonp

  关于jsonp,在这里已经讲得很清楚了。这次主要讲jQuery中的jsonp。原理都一样,表现形式不同而已。
  简单得说,对于一个ajax请求,如果涉及到跨域操作,那么浏览器肯定会报错。除非服务器端设置了头部信息"Access-Control-Allow-Origin:*"。如果在ajax请求中加上dataType:"jsonp",并且在url后面加上一个参数callback=?(请求的是纯数据,不是callback(data)的形式)。jQuery会将”?”替换为它自己定义的函数名,这个函数名与success的函数名是一样的。并将请求到的数据作为data参数传入success函数。对于一些接口来说,可能返回的就是callback(data)的形式,那么我们就要根据接口来指定回调函数。比如百度搜索的接口就是使用的cb=?cb参数作为回调。而不再是callback。
  

$.ajax({
  type:'get',
  url:'http://suggestion.baidu.com/su?wd=d&p=3&cb=?',
  dataType:'jsonp',
  success:function (data){
    console.log(data);
  },
  error:function(){
    alert('error')
  }
})

模拟百度搜索

jqXHR

  jQuery中所有的ajax方法都会返回jqXHR对象。只要把这个对象保存起来,随后就可以方便地使用这些属性和方法。
  在上面的关于$.ajax参数设置的时候,有success、error、complete回调函数。如果使用jqXHR对象的话,可以使用.done()、.error()、.always()来代替。
  jqXHR.done(function( data, textStatus, jqXHR ) {});
  jqXHR.fail(function( jqXHR, textStatus, errorThrown ) {});
  jqXHR.always(function( data|jqXHR, textStatus, jqXHR|errorThrown ) { });
  使用 jqXHR 的连缀方式比$.ajax()的属性方式有三大好处:

  • 可连缀操作,可读性大大提高;
  • 可以多次执行同一个回调函数;

    jqXHR.done(response).done(response);

  • 为多个操作指定回调函数;
$.when(jqXHR, jqXHR2).done(function (r1,r2) {
  alert(r1[0]);
  alert(r2[0]);
});

缓存相应

  如果想重复使用同一段数据,那么重复发送Ajax请求显示是一种浪费。为了编码这样做,我可以吧返回的jqXHR缓存在一个对象中。在需要使用这些数据时,可以先去这个对象寻找。如果有,就直接使用,如果没有,则需要发送Ajax请求,再将返回的jqXHR缓存起来。
  

<form>
  <input type="text" placeholder="请输入搜索内容"/>
  <button>提交</button>
</form>
var jqXHRs = {};
$( 'form' ).submit( function ( e ) {
  e.preventDefault();
  var search = $( 'input' ).val();
  if ( !jqXHRS[search] ) {
    jqXHRS[search] = $.ajax({
      url: 'someURL',
      dataType: 'jsonp',
      data: 'title=' + search,
      timeout: 15000
    })
  }
  jqXHRS[search].done( successHandle ).fail( failHandle ).always( completeHandle );
})

  通过这种方法,就可以消除重复的请求。

截流Ajax请求

  实现搜索功能时,越来越常见的是在用户输入过程动态地列出搜索结果来。通过给keyup事件绑定一个处理程序,来实现实时搜索功能。
  在缓存响应部分,我们已经节省了一些请求了。不过,通过截流请求,还可以进一步减少服务器的负担。
  

var 
  searchTimeout = null,
  searchDelay = 300
;
$( '#title' ).keyup( function () {
  clearTimeout( searchTimeout );
  searchTimeout = setTimeout( function () {
    $( 'form' ).trigger( 'submit' ); 
  },searchDelay)
})

  在用户第一次松开键时设置一个定时器,之后每次松开都会重置定时器并设置一个新的定时器。只有用户停止击键后超过预定的300毫秒后,才会触发 “submit” 事件。

数据类型转换器

  要定义一种新的数据类型,需要给$.ajaxSetup传递三个参数:accepts、contents和converters。其中,accepts属性会添加发送到服务器的头部信息,声明我们的脚本可以理解的特定的MIME类型;contents属性处理数据交换的另一方,它提供一个与相应的MIME类型进行匹配的正则表达式,以尝试自动检测这个元数据当中的数据类型。最后converters中包含解析返回数据的函数。
  

$.ajaxSetup({
   accepts: {
     yaml: 'application/x-yaml, text/yaml'
   },
   contents: {
     yaml: /yaml/,
   },
   converters: {
     'text yaml': function ( textValue ) {
       console.log( textValue );
       return;
     }
   }
 })
 $.ajax({
   url: 'categories.yml',
   dataType: 'yaml'
 })

  上述代码中,$.ajax()读取了一个YAML文件并把数据类型声明为yaml。因为到来的数据会按照text格式解析,jQuery需要一种机制能把一种数据类型转换为另一种数据类型。converters的’text yaml’告诉jQuery,这个转换函数以text格式接收数据,然后以yaml格式解析。
  在转换函数内部,我们只是把文本内容记录到控制台中,以便验证这个函数能够被正确调用。要实现实际地转换,需要加载第三方的YAML解析库(yaml.js)并调用其方法。

ajaxPrefilter

  $.ajaxPrefilter( [dataTypes ], handler )
  所谓预过滤器,就是一些回调函数,他们可以在发送请求前对请求进行过滤。预过滤器会在$.ajax()修改或在使用它的任何选项之前调用,因此通过预过滤器可以修改这些选项或基于新的、自定义选项发送请求。
  一个典型的预处理器如下:

$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
  // Modify options, control originalOptions, store jqXHR, etc
});
  • options:ajax请求对象(setting)。
  • originalOptions:作为一个默认options提供给$.ajax()。类似于$.ajaxSetup。我的测试结果是,如果originalOptions和$.ajaxSetup有相同的键,那么值以$.ajaxSetup为准
  • jqXHR:请求返回的jqXHR对象。

修改options

var currentRequests = {};

$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
  if ( options.abortOnRetry ) {
    if ( currentRequests[ options.url ] ) {
      currentRequests[ options.url ].abort();
    }
    currentRequests[ options.url ] = jqXHR;
  }
});

  如果ajax请求相同的url并且options.abortOnRetry设置为true,那么这个请求会被abort()。

$.ajaxPrefilter(function( options ) {
  if ( options.crossDomain ) {
    options.url = "http://mydomain.net/proxy/" + encodeURIComponent( options.url );
    options.crossDomain = false;
  }
});

  如果是跨域请求,添加上域名。

过滤特定的dataType

$.ajaxPrefilter( "json script", function( options, originalOptions, jqXHR ) {
  // Modify options, control originalOptions, store jqXHR, etc
});

  如果设置了第一个参数dataType,那么预过滤器只会验证dataType定义的数据类型。比如上述只验证dataType是json或者script的请求。

自定义dataType

$.ajaxPrefilter(function( options ) {
  if ( isActuallyScript( options.url ) ) {
    return "script";
  }
});

  检测options.url,如果是script类型,那么就设置它的dataType为script。

$.ajaxTransport

  transport是最高级的一种增强ajax的方法。当数据类型转换器和预过滤器都无法解决时可以采用它。
  $.ajaxTransport( dataType, handler )
  handler: function( options, originalOptions, jqXHR )。这三个参数在预过滤器已经说过。
  
  handler函数返回一个带有.send()和.abort()方法的对象。其中.send()方法负责发送请求,处理相应并把数据发送给回调函数。而.abort()方法会立即停止请求。

$.ajaxTransport( dataType, function( options, originalOptions, jqXHR ) {
  if( /* transportCanHandleRequest */ ) {
    return {
      send: function( headers, completeCallback ) {
        // Send code
      },
      abort: function() {
        // Abort code
      }
    };
  }
});

headers: 是一个键值对的请求头对象,如果transport支持它,就会传送它
complete: function( status, statusText, responses, headers ) {}
  

  • response:一个键值对对象。键是transport能够支持的dataType,值是返回给 success回调函数/done中的回调函数 的data。

      具体的在jquery api
      下面给出具体代码使ajax能够解析图像文件。
      

<script type="text/javascript">
    $.ajaxTransport( 'img', function ( settings ) {
      var $img, img, prop;
      return {
        send: function ( headers, complete ) {
          $img = $( '<img>', {
            src: settings.url
          });
          img = $img[0];
          prop = typeof img.naturalWidth ? 'width' : 'naturalWidth';
          if ( img.complete ) {
            callback( !!img[prop] );
          } else {
            $img.on( 'load error', function ( event ) {
              callback( event.type == 'load' );
            })
          }
          function callback( success ) {
            if ( success ) {
              complete( 200, 'OK', { img: img });
            } else {
              $img.remove();
              complete( 404, ' Not Found ');
            }
          }
        },
        abort: function () {
          if ( $img ) {
            $img.remove();
          }
        }
      }
    })
    $( document ).ready( function () {
      $.ajax({
        url: 'img/HBuilder.png',
        dataType: 'img'
      }).done( function ( img ) {
        $('<div></div>', {
          id: 'picture',
          html: img
        }).appendTo( 'body' );
      }).fail( function (xhr, textStatus, msg) {
        $( '<div></div>', {
          id: 'picture',
          html: textStatus + ':' + msg
        }).appendTo( 'body' );
      })
    })
</script>

  本来ajax是不支持图像文件的,但是经过ajaxTransport后,就可以支持图像文件了。
  这里写图片描述

小结

  1,基础:从load讲起,依次有get、post、getJSON、getScript、ajax
  2,增强:jsonp、全局函数、jqXHR
  3,高级:缓存相应,截流、数据类型转换、预过滤器、替代传输机制。
  4,工具函数:serialize、serializeArray、$.param
  5,既然选择了程序员这条路,那就走下去。

参考

jQuery基础教程(第四版)

jQuery官方API

李炎恢jQuery视频讲义
  

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值