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异步详解

转载于:https://www.cnblogs.com/JoannaQ/p/3679622.html

猜你喜欢

转载自blog.csdn.net/weixin_33991418/article/details/93057269
今日推荐