Ajax的进阶学习(二)
JSON和JSONP
如果在同一个域下,$.ajax()方法只要设置dataType属性即可加载JSON文件。而在非同域下,可以使用JSONP,但也是有条件的。
Ajax进阶.html:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Ajax进阶</title> <script type="text/javascript" src="jquery-1.12.3.js"></script> <script type="text/javascript" src="demo.js"></script> <link rel="stylesheet" type="text/css" href="style.css" /> </head> <body> <form> 用户名:<input type="text" name="user" /> 邮 件:<input type="text" name="email" /> <input type="radio" name="sex" value="男" />男 <input type="radio" name="sex" value="女" />女 <input type="button" value="提交" /> </form> <span class="loading">正在加载中...</span> <div id="box"> </div> </body> </html>
tomcat服务器端test.json:
[ { "url" : "www.ycku.com" } ]
若没有声明dataType(即dataType:"html"):
$("form input[type=button]").click(function() { $.ajax({ type:"post", url:"test.json", success:function(response, status, xhr) { alert(response); //若没有声明dataType(即dataType:"html"),test.json的整个文件内容都会返回(连带test.json的标签) alert(response[0].url); //若没有声明dataType(即dataType:"html"),返回undefined } }); });
所以,需要声明返回的类型是“json”,$.ajax()加载JSON文件:
$("form input[type=button]").click(function() { $.ajax({ type:"post", url:"test.json", dataType:"json", success:function(response, status, xhr) { alert(response); //[object Object] alert(response[0].url); //www.ycku.com } }); });
现在来看跨域处理问题。
一、①本地获取,本地tomcat服务器端有jsonp.php文件:(也不知道嘛意思?)
<?php //这个文件是远程端:http://www.li.cc/jsonp.php $_arr = array('a'=>1,'b'=>2,'c'=>3); $_result = json_encode($_arr); echo $_result; ?>
//本地获取jsonp.php文件,成功 $("form input[type=button]").click(function() { $.ajax({ type:"post", url:"jsonp.php", dataType:"json", success:function(response, status, xhr) { //alert(response); console.log(response); alert(response.a); //1 本地获取没问题 } }); });
②跨域获取,将jsonp.php文件放在远程端http://www.li.cc
//跨域获取jsonp.php文件,失败 $("form input[type=button]").click(function() { $.ajax({ type:"post", url:"http://www.ll.cc/jsonp.php", dataType:"json", success:function(response, status, xhr) { //alert(response); console.log(response); alert(response.a); } }); });
二、①本地获取,本地tomcat服务器端有jsonp2.php文件:
如果想跨域操作文件的话,我们就必须使用JSONP。JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
<?php //这个文件是远程端:http://www.li.cc/jsonp2.php $_arr = array('a'=>1,'b'=>2,'c'=>3); $_result = json_encode($_arr); $_callback = $_GET['callback']; echo $_callback."($_result)"; ?>
//本地获取jsonp2.php文件,成功 $("form input[type=button]").click(function() { $.getJSON("jsonp2.php?callback=?", function() { alert(response.a); // 1 console.log(response); }); });
url中参数callback值的可以是任意数,也可传一个?(会生成一个随机数),如上,会发现传过去的是诸如:
callback=jQuery112305981071515026646_1461671727709&_=1461671727710
②$.getJSON()方法跨域获取JSON
$("form input[type=button]").click(function() { $.getJSON("http://www.ll.cc/jsonp2.php?callback=?", function() { alert(response.a); // 1 console.log(response); }); });
$.ajax()方法跨域获取JSON:
$("form input[type=button]").click(function() { $.ajax({ type:"post", url:"http://www.ll.cc/jsonp2.php?callback=?", dataType:"json", success:function(response, status, xhr) { //alert(response); console.log(response); alert(response.a); } }); });
因为返回类型不是jsonp,所以无法达到我们预期的效果,所以应修改为:
$("form input[type=button]").click(function() { $.ajax({ type:"post", url:"http://www.ll.cc/jsonp2.php?callback=?", dataType:"jsonp", success:function(response, status, xhr) { //alert(response); console.log(response); alert(response.a); } }); });
jqXHR对象
在之前,我们使用了局部方法:.success()、.complete()和.error()。这三个局部方法并不是XMLHttpRequest对象调用的,而是$.ajax()之类的全局方法返回的对象调用的。 这个对象,就是jqXHR对象,它是原生对象XHR的一个超集。
获取jqXHR对象,查看属性和方法
$("form input[type=button]").click(function() { //jqXHR就是$.ajax()返回的对象 var jqXHR = $.ajax({ type:"post", url:"user.php", data:$("form").serialize() }); jqXHR.success(function(response) { alert(response); }); });
注意:如果使用jqXHR对象的话,那么建议用.done()、.always()和.fail()代替.success()、.complete()和.error(),因为在未来版本中,很可能将这三种方法废弃取消。
$("form input[type=button]").click(function() { //jqXHR就是$.ajax()返回的对象 var jqXHR = $.ajax({ type:"post", url:"user.php", data:$("form").serialize() }); jqXHR.done(function(response) { alert(response); }); });
使用jqXHR的连缀方式比$.ajax()的属性方式有三大好处:
1.可连缀操作,可读性大大提高
2.可以多次执行同一个回调函数
3.为多个操作指定回调函数
来看第1、2点:
$("form input[type=button]").click(function() { //jqXHR就是$.ajax()返回的对象 var jqXHR = $.ajax({ type:"post", url:"user.php", data:$("form").serialize() }); jqXHR.done(function(response) { //可连缀操作,多次执行同一个回调函数(done()) alert(response + "1"); }).done(function(response) { alert(response + "2"); }); jqXHR.done(function(response) { alert(response + "3"); }); });
再来看第3点:
有t1.php文件如下:
<?php echo "test1.php"; ?>
t2.php文件如下:
<?php echo "test2.php"; ?>
$("form input[type=button]").click(function() { var jqXHR = $.ajax("t1.php");//ajax()也可直接传一个url var jqXHR2 = $.ajax("t2.php"); //这是我们本能想到的 /* jqXHR.done(function(response) { alert(response); }); jqXHR2.done(function(response) { alert(response); }); */ //多个操作指定回调函数 $.when(jqXHR, jqXHR2).done(function(r1, r2) { alert(r1[0]); //alert(r1)-->test1.pph,success,[object Object],object为r1的jqXHR对象 alert(r2[0]); }); });