Ajax的进阶学习(二)

时间:2024-04-06 10:37:35

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); //
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); //
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]);
});
});