• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Joanna Qian
Stay Hungry, Stay Foolish!
博客园    首页    新随笔    联系   管理    订阅  订阅
jQuery学习小结3——AJAX

一、jQuery的Ajax方法

jQuery对Ajax 做了大量的封装,使用起来也较为方便,不需要去考虑浏览器兼容性。对于封装的方式,jQuery 采用了三层封装:

  • 最底层的封装方法为——$.ajax()
  • 而通过这层封装了第二层有三种方法——.load()、$.get()和$.post()
  • 最高层是——$.getScript()和$.getJSON()方法

1.1 .load()方法 —— 载入远程 HTML 文件代码并插入至 DOM 中

   load(url, [data], [callback])

  • load是局部方法,需要一个包含元素的jQuery 对象作为前缀,对于用途而言,.load()适合做静态文件的异步获取
  • url:待装入 HTML 网页网址。
  • data:发送至服务器的 key/value 数据。在jQuery 1.3中也可以接受一个字符串了。向服务器提交数据有两种方式:get 和post。
//不传递data,则默认get 方式,data使用?方式
$('input').click(function () {
    $('#box').load('test.php?url=ycku');
});
//传递data,则为post 方式,data必须使用键值对方式
$('input').click(function () {
    $('#box').load('test.php', {
        url : 'ycku'
    });
});
  • callback:载入成功时回调函数,其参数如下图

回调函数callback也可以传递三个可选参数:

  • responseText(请求返回):
  • status(请求状态): 如果成功返回数据则为:success,否则为:error
  • XMLHttpRequest(XMLHttpRequest 对象):否则为:error
$('input').click(function () {
    $('#box').load('test.php', {
        url : 'ycku'
    }, function (response, status, xhr) {
        alert('返回的值为:' + response + ',状态为:' + status + ',状态是:' + xhr.statusText);
    });
});

 1.2 $.get()和$.post()

jQuery.get(url, [data], [callback], [type])

jQuery.post(url, [data], [callback], [type])

  • $.get()和$.post()是全局方法,无须指定某个元素。对于用途而言,.load()适合做静态文件的异步获取,
    而对于需要传递参数到服务器页面的,$.get()和$.post()更加合适
  • url:发送请求地址。
  • data:待发送 Key/value参数
//通过直接在url问号紧跟传参    
    $('input').click(function () {
        $.get('test.php', 'url=ycku',function (response, status, xhr) {
            $('#box').html(response);
        });
    });
    
//通过第二个参数data,字符串形式的键值对传参,然后自动转换为问号紧跟传参    
    $('input').click(function () {
        $.get('test.php', {
            url : 'ycku'
        },function (response, status, xhr) {
            $('#box').html(response);
        });
    });
    
//通过第二个参数data,对象形式的键值对传参,然后自动转换为问号紧跟传参
    $('input').click(function () {
        $.post('test.php?url=ycku', function (response, status, xhr) {
            $('#box').html(response);
        });
    });
    
//post提交不能使用问号传参    
    $('input').click(function () {
        $.post('test.php', 'url=ycku',function (response, status, xhr) {
            $('#box').html(response);
        });
    });
    
//post提交可以使用字符串形式的键值对传参,自动转换为http消息实体传参    
    $('input').click(function () {
        $.post('test.php', {
            url : 'ycku'
        },function (response, status, xhr) {
            $('#box').html(response);
        });
    });
    
//post提交可以使用对象键值对    
    $('input').click(function () {
        $.post('test.php', {
            url : 'ycku'
        },function (response, status, xhr) {
            $('#box').html(response);
        }, 'html');                                                    //PHP文件返回的数据是纯文本,默认是html或text
    });
data数据格式
  • callback:发送成功时回调函数。
  • type:返回内容格式,xml, html, script, json, text, _default,。一般情况下type 参数是智能判断,并不
    需要我们主动设置,如果主动设置,则会强行按照指定类型格式返回。
//使用$.get()异步返回html 类型
$('input').click(function () {
    $.get('test.php', {
        url : 'ycku'
    }, function (response,status, xhr) {
        if (status == 'success') {
            $('#box').html(response);
    }
    })  //type 自动转为html
});    
//本身是纯文本,如果强行按照xml或者json数据格式返回的话,那么就无法获取数据    
    $('input').click(function () {
        $.post('test.xml',function (response, status, xhr) {
            alert(response);
        }, 'html');     //默认type就已经是xml        
    }); 
    
//如果默认已经是xml,强行设置为html,则会连xml标签也返回    
    $('input').click(function () {
        $.post('test.xml',function (response, status, xhr) {
            alert($(response).find('root').find('url').text());
        });                                                                    
    });

$.post()方法的使用和$.get()基本上一致,他们之间的区别也比较隐晦,基本都是背后的不同,在用户使用上体现不出。具体区别如下:

  • .GET请求是通过URL提交的,而POST 请求则是HTTP消息实体提交的;
  • .GET提交有大小限制(2KB),而POST 方式不受限制;
  • .GET方式会被缓存下来,可能有安全性问题,而POST没有这个问题;
  • .GET方式通过$_GET[]获取,POST 方式通过$_POST[]获取。

1.3 $.getScript()和$.getJSON()

jQuery 提供了一组用于特定异步加载的方法:

  • $.getScript()——能够特定的情况再加载JS 文件,而不是一开始把所有JS 文件都加载了
  • $.getJSON()——用于专门加载JSON 文件
//点击按钮后再加载JS 文件
$('input').click(function () {
    $.getScript('test.js');
});
//$.getJSON()方法是专门用于加载JSON 文件的,使用方法和之前的类似
$('input').click(function () {
    $.getJSON('test.json', function (response, status, xhr) {
        alert(response[0].url);
    });
});

1.4 .$.ajax()

   jQuery.ajax(url,[settings])

  • $.ajax()是所有ajax 方法中最底层的方法,所有其他方法都是基于$.ajax()方法的封装。
  • 最简单的情况下,$.ajax()可以不带任何参数直接使用。

注意,所有的选项都可以通过$.ajaxSetup()函数来全局设置

$('form input[type=button]').click(function () {
    $.ajaxSetup({
        type : 'POST',
        url : 'test.php',
        data : $('form').serialize()
    });
    $.ajax({
        success : function (response, status, xhr) {
            alert(response);
        }
    });
});
$.ajaxSetup

//$.ajax 使用
$('input').click(function () {
    $.ajax({
        type : 'POST', //这里可以换成GET
        url : 'test.php',
        data : {
        url : 'ycku'
    },
    success : function (response, stutas, xhr) {
        $('#box').html(response);
    }
    });
});
$.ajax({
     type : 'POST',
     url : 'user.php',
     data : $('form').serialize(),
     success : function (response, status, xhr) {
          alert('请求成功后');
     },
     complete : function () {
          alert('请求完成后,不管是否失败成功');
     },
     beforeSend : function () {
            alert('发送请求之前执行');
     },
     error : function () {
           alert('请求失败后');
     }
});

1.5 表单序列化.serialize(),.serializeArray()

  • .serialize()
  • .serializeArray() —— 返回JSON 数据的方法
//使用.serialize()序列化表单内容
$('form input[type=button]').click(function () {
    $.ajax({
        type : 'POST',
        url : 'test.php',
        data : $('form').serialize(),
        success : function (response, status, xhr) {
            alert(response);
        }
    });
});

1.6 jQuery.param(obj,[traditional])——将表单元素数组或者对象序列化。是.serialize()的核心方法

var myObject = {
  a: {
    one: 1, 
    two: 2, 
    three: 3
  }, 
  b: [1,2,3]
};
var recursiveEncoded = $.param(myObject);
var recursiveDecoded = decodeURIComponent($.param(myObject));
alert(recursiveEncoded);
//a%5Bone%5D=1&a%5Btwo%5D=2&a%5Bthree%5D=3&b%5B%5D=1&b%5B%5D=2&b%5B%5D=3
alert(recursiveDecoded);
//a[one]=1&a[two]=2&a[three]=3&b[]=1&b[]=2&b[]=3

var shallowEncoded = $.param(myObject, true);    //a=%5Bobject+Object%5D&b=1&b=2&b=3
var shallowDecoded = decodeURIComponent(shallowEncoded);   //a=[object+Object]&b=1&b=2&b=3

注意: 因为有时程序对于复杂的序列化解析能力有限,serialize()虽然encode字符,但使用$.param()将对象形式的键值对转为URL 地址的字符串键值对,可以更加稳定准确的传递表单内容。

二、请求全局事件方法

  • 全局事件——每次Ajax请求都会触发,它会向DOM中的所有元素广播

jQuery新版本规定请求全局事件方法是所有Ajax请求都会触发到,并且只能绑定在document元素上(若绑定多次,则会依次触发为事件注册的回调函数),而局部方法,只针对某个Ajax请求

//$.post()使用局部方法.success()
$.post('test.php', $('form').serialize(), function (response, status, xhr) {
    $('#box').html(response);
}).success(function (response, status, xhr) {
    alert(response);
});
//$.post()使用全局事件方法.ajaxSuccess()
$(document).ajaxSuccess(function (event, xhr, settings) {
    alert(xhr.responseText);
});

ajaxStart

开始新的Ajax请求,并且此时jQuery对象上没有其他ajax请求正在进行。

签名:function(e)

函数说明:传入事件对象

ajaxSend

当一个Ajax请求开始时触发

签名:function(e,jqXHR,s)

函数说明:传入事件对象、jqXHR、s对象

ajaxSuccess

全局的请求成功

签名:function(e,jqXHR,s,data)

函数说明:传入事件对象、jqXHR、s对象、请求成功返回的相应数据

ajaxError

全局的发生错误时触发

签名:function(e,jqXHR,s,errorData)

函数说明:传入事件对象、jqXHR、s对象、请求失败返回的错误信息

ajaxComplete

全局的请求完成时触发

签名:function(e,jqXHR,s)

函数说明:传入事件对象、jqXHR、s对象

ajaxStop

当jQuery对象上正在进行Ajax请求都结束时触发。

签名:function(e)

函数说明:传入事件对象

. 如果某个ajax不想触发全局事件,可以设置取消

$.ajax({global : false});

.  如果请求时间太长,可以设置超时

$.ajax({timeout : 500});
  •  .ajaxStart()、.ajaxStop()——加载请求

请求加载提示的显示和隐藏

$(document).ajaxStart(function () {
        $('.loading').show();
    }).ajaxStop(function () {
        $('.loading').hide();
});
  • .ajaxError(),参见后面
  • .ajaxSuccess(),对应一个局部方法:.success(),请求成功时候调用
  • .ajaxComplete(),对应一个局部方法:.complete(),请求完成后调用
  • .ajaxSend(),没有局部方法,只有属性beforeSend,请求发生之前要绑定的函数

image

// 全局事件
$("#div_event").ajaxStart(function (e) {
    doAddEvent4textarea('txt_event', '触发ajaxStart回调函数');
});
$("#div_event").ajaxSend(function (e) {
    doAddEvent4textarea('txt_event', '触发ajaxSend回调函数');
});
$("#div_event").ajaxSuccess(function (e, jqXHR, s, data) {
    doAddEvent4textarea('txt_event', '触发ajaxSuccess回调函数');
});
$("#div_event").ajaxError(function (e, jqXHR, s, errorData) {
    doAddEvent4textarea('txt_event', '触发ajaxError回调函数');
});
$("#div_event").ajaxComplete(function (e, jqXHR, s) {
    doAddEvent4textarea('txt_event', '触发ajaxComplete回调函数');
});
$("#div_event").ajaxStop(function (e) {
    doAddEvent4textarea('txt_event', '触发ajaxStop回调函数');
});
// 局部事件
function bindLocalEvent(e) {
    var textareaid = e.data.textareaid;
    var global = e.data.global;
 
    $.ajax('AjaxHandler.ashx?func=btn_nowTime_long',
        {
            type: 'get',
            dataType: 'text',
            global: global,
            cache: false,
            beforeSend: function (jqXHR, s) {
                doAddEvent4textarea(textareaid, '触发beforeSend回调函数');
            },
            dataFilter: function (data, dataType) {
                doAddEvent4textarea(textareaid, '触发dataFilter回调函数');
            },
            success: function (data, statusText, jqXHR) {
                doAddEvent4textarea(textareaid, '触发success回调函数');
            },
            error: function (jqXHR, textStatus, errorThrown) {
                doAddEvent4textarea(textareaid, '触发error回调函数');
            },
            complete: function (jqXHR, textStatus) {
                doAddEvent4textarea(textareaid, '触发complete回调函数');
            }
        });
}
function doAddEvent4textarea(textareaid, txt) {
    var textarea = $("#" + textareaid);
    textarea.val(textarea.val() + '\r\n' + txt);
}
示例:$.ajax()触发的事件(局部事件和全局事件)

三、错误处理

  • jQuery1.5之前$.get()、$.post()、.load()方法通过全局.ajaxError()事件方法来返回错误信息
  • jQuery1.5之后,通过连缀处理局部.error()方法
  • $.ajax()可以用以上两个方法,也可以使用自己的属性方法error : function () {}
//$.ajax()使用属性提示错误
$.ajax({
  type : 'POST',
  url : 'test1.php',
  data : $('form').serialize(),
  success : function (response, status, xhr) {
    $('#box').html(response);
  },
  error : function (xhr, errorText, errorStatus) {
    alert(xhr.status + ':' + xhr.statusText);
  }
});
//$.post()使用.error()方法提示错误,该方法将被fail()替代
$.post('test1.php').error(function (xhr, status, info) {
  alert(xhr.status + ':' +xhr.statusText);
  alert(status + ':' + info);
});
//$.post()使用全局.ajaxError()事件提示错误
$(document).ajaxError(function (event, xhr, settings, infoError) {
  alert(xhr.status + ':' +xhr.statusText);
  alert(settings+ ':' + info);
});

四、跨域操作——JSON和JSONP

在JavaScript中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略——所谓同源是指,域名host,协议protocol,端口port相同)。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容。

  4.1 $.ajax()跨域原理分析

由于javascript的安全限制“同源策略”,所以我们无法使用XMLHttpRequest直接请求别的域名下的资源。不过拥有src属性和href属性的<script>\<img>\<iframe>和<link>\<a>标签不受同源策略影响。$.ajax()提供的两种解决方案正是应用了动态创建<script>的方式来实现(即:生成<script>标签,src引入脚本,然后执行,最后移除<script>标签)。

   4.2 跨域解决方法

① JSONP(JSON with padding)是一个非官方的协议,它容许在服务器端集成Script tags返回客户端,通过javascript callback的形式实现跨域访问。如果想跨域调用文件,必须使用JSONP。

② callback方法

//跨域的PHP端
<?php
$arr = array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
$result = json_encode($arr);
$callback = $_GET['callback'];
echo $callback."($result)";
?>
//$.getJSON()方法跨域获取JSON,使用?callback=?方法
$.getJSON('http://www.li.cc/test.php?callback=?', function (response) {
  console.log(response);
});
//$.ajax()方法跨域获取JSON,使用?callback=?方法
$.ajax({
  url : 'http://www.li.cc/test.php?callback=?',
  dataType : 'json',
  success : function (response, status, xhr) {
    console.log(response);
    alert(response.a);
  }
});
//$.ajax()获取远程数据,使用jsonp方法
 $.ajax({
    type : 'POST',
    url : 'http://www.li.cc/jsonp2.php',
    dataType : 'jsonp',
    success : function (response, status, xhr) {
        console.log(response);
        ert(response.a);
      }
 });

说明;

  • 不会触发全局事件和局部事件;只支持GET方式(POST请求会自动转化为GET请求);默认不启用缓存(cache:false)
  • jsonp方式可以通过jsonp和jsonpCallback参数指定一个特定回调函数

五、jqXHR对象

jQuery定义了一个jqXHR对象,它是原生对象XHR的一个超集(为不同浏览器内置的XMLHttpRequest提供了一致的超集),jqXHR对象我们常常使用如下成员,这些成员主要用于ajax的全局事件和局部事件,并且做为$.ajax()函数返回值返回。

jqXHR:{
    readyState
    ,setRequestHeader: function( name, value )
    ,getAllResponseHeaders: function()
    ,getResponseHeader: function( key )
    ,overrideMimeType: function( type )
    ,abort: function( statusText )
    ,responseText
    ,responseXML
}

jqXHR的全部成员如下

var jqXHR = $.ajax({
    type : 'POST',
    url : 'test.php',
    data : $('form').serialize()
});
for (var i in jqXHR) {
    document.write(i + '<br />');
}
查看jqXHR对象的全部属性和方法

建议用jqXHR 的.done()、.always()、.fail()来代替.success()、.complete()、.error()。未来版本中,这三种方法可能被废弃取消

jqXHR.done(function (response) {
    $('#box').html(response);
});

使用jqXHR的连缀方式比$.ajax()的属性方式有三大优点:

  • 可以连缀操作,可读性大大提高
  • 可以多次执行同一个回调函数
  • 可以为多个操作指定回调函数
//$.ajax多个成功后,提交的是第二个(最后一个)
$.ajax({
    type : 'POST',
    url : 'user.php',
    data : $('form').serialize()
    success: function(response,status,xhr){
        alert(response+"1");
    },
    success: function(response,status,xhr){
        alert(response+"2");   
    }
});
//jqXHR可以同时执行多个成功后的回调函数
jqXHR.done().done();
//多个操作指定同回调函数
var jqXHR = $.ajax('test.php');
var jqXHR2 = $.ajax('test2.php');
$.when(jqXHR, jqXHR2).done(function (r1,r2) {
    alert(r1[0]);
    alert(r2[0]);
});

参考:  触碰jQuery:AJAX异步详解

posted on 2014-04-22 02:12  Joanna Qian  阅读(555)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3