Ajax 解释Ajax的XML和JSON格式,操作Ajax的几种封装方法【案例+解释】(二)

1.Ajax同步的使用

一般在网页中,是不使用Ajax的同步的,因为同步,就必须依次执行,比较考验网络状况。这就像一个人在寄快递一样,同步,就必须把快递寄送完成,才能干其他事情,异步,再寄送完成前,就可以操作其他事情,就这么好理解。

下面,只是写一个和之前一样register.html中的username,只不过这里使用的是同步。

username.onblur = function(){
	var usernameValue = username.value;
	console.log(usernameValue);
	//这里比较用户名username和服务器数据库里面内容。
	//往后使用ajax来实现。
	var xhr = null;
	if(window.XMLHttpRequest){
		xhr = new XMLHttpRequest();
	}else{
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}
	xhr.open("get","./server/checkUsername.php?uname="+usernameValue,false);
	xhr.send(null);
	console.log(xhr.readyState);
	xhr.onreadystatechange = function(){
		if (xhr.readyState==4) {
			if (xhr.status==200) {
				//responseText返回的是字符串
				//responseXML返回的是XML格式
				var result = xhr.responseText;
				console.log(result);
				var username_result = document.querySelector("#username_result");
				if (result == "NO") {
					username_result.innerText = "user已经注册!!";
				}else{
					username_result.innerText = "user可以使用。";
				}
			}
		}
	}
};

onreadystatechange事件,只有readyState的值变化时,才会被执行。
上面代码,使用的是同步,但是却不执行回调函数,因为在xhr.send()的时候,这里是同步执行的,不会执行下面的onreadystatechange事件,一直到send()方法执行完,这里的xhr.readyState为4,就不会再执行onreadystatechange这个事件,因此用不到onreadystatechange事件。

将onreadystatechange事件去掉就可以正常运行了,如下:

username.onblur = function(){
		var usernameValue = username.value;
		console.log(usernameValue);
		//这里比较用户名username和服务器数据库里面内容。
		//往后使用ajax来实现。
		var xhr = null;
		if(window.XMLHttpRequest){
			xhr = new XMLHttpRequest();
		}else{
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		}
		xhr.open("get","./server/checkUsername.php?uname="+usernameValue,false);
		xhr.send(null);
		console.log(xhr.readyState);
		if (xhr.readyState==4) {
				if (xhr.status==200) {
					//responseText返回的是字符串
					//responseXML返回的是XML格式
					var result = xhr.responseText;
					console.log(result);
					var username_result = document.querySelector("#username_result");
					if (result == "NO") {
						username_result.innerText = "user已经注册!!";
					}else{
						username_result.innerText = "user可以使用。";
					}
				}
		}
	};

2.JS的单线程和事件队列

这里涉及到一个队列问题,因为JS是单线程的,开始有一个事件队列,事件队列的作用就是用来存放事件的函数,浏览器开始先执行完所有的代码,然后去事件队列,执行事件的函数,就像下图一样。

在这里插入图片描述

window.onload = function(){},这样类似的也是要放入到事件队列中,然后被执行。
注意:浏览器不是单线程的!!

2.Ajax的数据格式

1.XML数据格式

xml数据格式将数据以标签的方式进行组装,标签成对,开头有相应的xml版本,编码,例如:<?xml version=''1.0'' encoding="utf-8" ?>

缺点:体积太大,传递慢,元数据太多,解析不方便,目前使用很少。
例如:

<?xml version=''1.0'' encoding="utf-8" ?>
<students>
	<student>
			<name>张三</name>
			<age>19</age>
			<sex></sex>	
	</student>
	<student>
			<name>李四</name>
			<age>23</age>
			<sex></sex>	
	</student>
	<student>
			<name>王五</name>
			<age>12</age>
			<sex></sex>	
	</student>
</students>

2.JSON数据格式

Json数据格式类似于JS中的对象方式,key-value的形式组装。

相比较xml格式,体积小,传输快,解析方便。

例如:

{
	"student":[
		{
			"name":"张三",
			"age":"19",
			"sex":"男"
		},
		{
			"name":"李四",
			"age":"23",
			"sex":"女"
		},
		{
			"name":"王五",
			"age":"12",
			"sex":"男"
		}
	]
}

这里说一下eval函数,evaluate意思评估。
eval() 函数使用的是 JavaScript 编译器,可解析 JSON 文本,然后生成 JavaScript 对象。必须把文本包围在括号中,这样才能避免语法错误:

var obj = eval ("(" + txt + ")");

在网页中使用 JavaScript 对象:

var txt = '{ "sites" : [' +
'{ "name":"菜鸟教程" , "url":"www.djznrobot.com" },' +
'{ "name":"google" , "url":"www.djznrobot.com" },' +
'{ "name":"微博" , "url":"www.djznrobot.com" } ]}';

var obj = eval ("(" + txt + ")");

document.getElementById("name").innerHTML=obj.sites[0].name
document.getElementById("url").innerHTML=obj.sites[0].url

3.如何处理XML数据格式案例

注意:在php文件中,xml代码和php代码中间一定不要有多余的换行,否则不能执行!!!

写一个案例,创建一个booklist.html文件:

<!DOCTYPE html>
<html>
<head>
	<title>
		书籍列表案例
	</title>
	<style type="text/css">
		div{
			width: 800px;
			margin: 20px auto;
		}
		table{
			width: 800px;
			margin: 20px auto;
			border-collapse: collapse;
		}
		th{
			background-color: #0094ff;
			color: white;
			font-size: 16px;
			padding: 5px;
			text-align: center;
			border: 1px solid black;
		}
		td{
			padding: 5px;
			text-align: center;
			border: 1px solid black;
		}
	</style>
	<script type="text/javascript">
		window.onload = function(){
			var xhr = new XMLHttpRequest();
			xhr.open("get","./server/getBooks.php",true);
			xhr.send(null);
			xhr.onreadystatechange = function(){
				if (xhr.readyState == 4) {
					if (xhr.status == 200) {
						var result = xhr.responseXML;
						var books = result.getElementsByTagName("booklist")[0].getElementsByTagName("book");
						var newHtml = document.getElementById("bookContaintor").innerHTML;
						for(var i=0;i<books.length;i++){
							var index = books[i];
							var name = index.getElementsByTagName("name")[0].textContent;
							var author = index.getElementsByTagName("author")[0].textContent;
							var desc = index.getElementsByTagName("desc")[0].textContent;
							var tempHTML = "<tr><td>"+name+"</td>"+"<td>"+author+"</td>"+"<td>"+desc+"</td></tr>";
							newHtml += tempHTML;
						}
						document.getElementById("bookContaintor").innerHTML = newHtml;
					}
				}
			}
		}
	</script>
</head>
<body>
	<div>
		<table id="bookContaintor">
			<tr>
				<th>书名</th>
				<th>作者</th>
				<th>描述</th>
			</tr>
		</table>
	</div>
</body>
</html>

再在server下创建一个getBooks.php文件:

<?php 
	//这里设置响应头信息,保证浏览器可以把相应内容识别为xml文件类型。
	header("Content-Type:text/xml;");
	$arr = array();
	$arr[0] = array("name"=>"三国演义","author"=>"罗贯中","desc"=>"一个杀戮的时代!");
	$arr[1] = array("name"=>"水浒传","author"=>"施耐庵","desc"=>"108条好汉的故事。");
	$arr[2] = array("name"=>"西游记","author"=>"吴承恩","desc"=>"佛教与道教的斗争。");
	$arr[3] = array("name"=>"红楼梦","author"=>"曹雪芹","desc"=>"一个封建王朝的缩影。");?>
<?xml version="1.0" encoding="utf-8" ?>
<booklist>
	<?php foreach ($arr as $key => $value) { ?>
	<book>
		<name><?php echo $value['name'] ?></name>
		<author><?php echo $value['author'] ?></author>
		<desc><?php echo $value['desc'] ?></desc>
	</book>
	<?php } ?>
</booklist>

结果如下:

在这里插入图片描述

4.如何处理JSON数据格式案例

注意:除了XML格式,其他的都是用responseText方法,responseText方法获得字符串形式的响应数据。。

3.Ajax的封装

将Ajax的四个操作步骤封装在一个函数当中,通过调用函数来实现Ajax调用。

下面我们就在之前的register.html,进行修改,建立一个myAjax的函数,来进行封装:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>register</title>
	<script type="text/javascript">

		function myAjax(type,url,params,dateType,callback){
			var xhr = null;
			if (window.XMLHttpRequest) {
				xhr = new XMLHttpRequest();
			}else{
				xhr = new ActiveXObject("Microsoft.XMLHTTP");
			}

			if (type == "get") {
				url += "?" + params;
			}

			xhr.open(type,url,true);
			if (type == "get") {
				xhr.send(null);
			} else if (type == "post") {
				xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
				xhr.send(params);
			}
			xhr.onreadystatechange = function(){
				if (xhr.readyState == 4 && xhr.status == 200) {
					var result = null;

					if (dateType == "json") {
						result = xhr.responseText;
						result = JSON.parse(result);
					}else if(dateType == "xml"){
						result = xhr.responseXML;
					}else{
						result = xhr.responseText;
					}

					callback(result);
				}
			}			
		}

		window.onload = function(){
			var username = document.querySelector("#username");
			var email = document.querySelector("#email");
			var phone = document.querySelector("#phone");

			username.onblur = function(){
				var usernameValue = username.value;
				var type = "get";
				var url = "./server/checkUsername.php";
				var params = "uname="+usernameValue;
				var dateType = "text";

				myAjax(type,url,params,dateType,function(result){
					var username_result = document.querySelector("#username_result");
					if (result == "NO") {
						username_result.innerText = "user已经注册!!";
					}else{
						username_result.innerText = "user可以使用。";
					}
				});
			}

			email.onblur = function(){
				var emailValue = email.value;

				var type = "post";
				var url = "./server/checkEmail.php";
				var params = "e="+ emailValue;
				var dateType = "text";

				myAjax(type,url,params,dateType,function(result){
					var email_result = document.querySelector("#email_result");
					if (result==0) {
						email_result.innerText = "邮箱可用";
					}else{
						email_result.innerText = "邮箱不可用";
					}
				});
			}

			phone.onblur = function(){
				var phoneValue = phone.value;
				var type = "post";
				var url = "./server/checkPhone.php";
				var params = "phonenumber="+phoneValue;
				var dateType = "json";

				myAjax(type,url,params,dateType,function(result){
					var phone_result = document.querySelector("#phone_result")
					if (result.status == 0 ) {
						//代表手机号码可用
						phone_result.innerText = result.message.tips+","+result.message.phonefrom;
					}else if (result.status == 1) {
						//代表手机号码不可用
						phone_result.innerText = result.message;
					}
				});
			}
		}
	</script>
</head>
<body>
	<h1>注册界面</h1>
	<form action="">
		用户名:<input type="text" id="username"><span id="username_result"></span><br>

		邮箱:<input type="text" id="email"><span id="email_result"></span><br>

		手机号码:<input type="text" id="phone"><span id="phone_result"></span>
	</form>
</body>
</html>

上面的myAjax()函数方法就是封装后的。不要忘记之前的三个php后台文件。

4.Ajax使用对象和外部JS文件

创建一个myutils.js文件,将封装起来的Ajax存入到里面:

里面通过使用对象解决了参数的顺序问题。

function myAjax2(obj){
	//使用对象来解决参数的顺序问题。
	//data就是要传递的参数,也就是之前的params,这里写成了对象的形式。
	//这里的参数形式差不多为,uname=zhangsan&age=18
	var defaults = {
		type:"get",
		url:"#",
		dataType:"json",
		data:{},
		async:true,
		success:function(result){
			console.log(result);
		}
	};

	//将obj的属性,覆盖到defaults中的属性。
	//既可以设置了默认值,又可以传递属性的值,一举两得。
	for(var key in obj){
		defaults[key] = obj[key];
	}

	var xhr = null;
	if (window.XMLHttpRequest) {
		xhr = new XMLHttpRequest();
	}else{
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}

	// data = {
	// 	uname:"zhangsan",
	// 	age:18
	// }
	// 参数形式差不多为,uname=zhangsan&age=18
	// 按照上面的格式来写出params。
	var params = "";
	for(var attr in defaults.data){
		params += attr + "=" + defaults.data[attr]+"&";
	}
	if (params) {
		params = params.substring(0,params.length-1);
	}
	if (defaults.type == "get") {
		defaults.url += "?" + params;
	}

	xhr.open(defaults.type,defaults.url,defaults.async);

	if (defaults.type == "get") {
		xhr.send(null);
	}else if (defaults.type == "post") {
		xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
		xhr.send(params);
	}

	if (defaults.async) {
		xhr.onreadystatechange = function(){
			if (xhr.readyState == 4 && xhr.status == 200) {
				if (defaults.dataType == "json") {
					result = xhr.responseText;
					result = JSON.parse(result);
				}else if (defaults.dataType == "xml") {
					result = xhr.responseXML;
				}else{
					result = xhr.responseText;
				}
				defaults.success(result);
			}
		}
	}else{
		if (xhr.readyState == 4 && xhr.status == 200) {
			if (defaults.dataType == "json") {
				result = xhr.responseText;
				result = JSON.parse(result);
			}else if (defaults.dataType == "xml") {
				result = xhr.responseXML;
			}else{
				result = xhr.responseText;
			}
			defaults.success(result);
		}
	}

}

修改之前的register.html,并导入上面的myutils.js,如下:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>register</title>
	<script type="text/javascript" src="myutils.js"></script>
	<script type="text/javascript">

		window.onload = function(){
			var username = document.querySelector("#username");
			var email = document.querySelector("#email");
			var phone = document.querySelector("#phone");

			username.onblur = function(){
				var usernameValue = username.value;
				var type = "get";
				var url = "./server/checkUsername.php";
				var params = "uname="+usernameValue;
				var dateType = "text";

				myAjax2({
					url:url,
					data:{uname:usernameValue},
					dataType:"text",
					success:function(result){
						var username_result = document.querySelector("#username_result");
						if (result == "NO") {
							username_result.innerText = "user已经注册!!";
						}else{
							username_result.innerText = "user可以使用。";
						}
					}
				});
			}

			email.onblur = function(){
				var emailValue = email.value;

				var type = "post";
				var url = "./server/checkEmail.php";
				var params = "e="+ emailValue;
				var dataType = "text";


				myAjax2({
					type:type,
					url:url,
					data:{e:emailValue},
					dataType:"text",
					success:function(){
						var email_result = document.querySelector("#email_result");
						if (result==0) {
							email_result.innerText = "邮箱可用";
						}else{
							email_result.innerText = "邮箱不可用";
						}
					}
				});
			}

			phone.onblur = function(){
				var phoneValue = phone.value;
				var type = "post";
				var url = "./server/checkPhone.php";
				var params = "phonenumber="+phoneValue;
				var dataType = "json";

				myAjax2({
					type:type,
					url:url,
					data:{phonenumber:phoneValue},
					dataType:"json",
					success:function(){
						var phone_result = document.querySelector("#phone_result")
						if (result.status == 0 ) {
							//代表手机号码可用
							phone_result.innerText = result.message.tips+","+result.message.phonefrom;
						}else if (result.status == 1) {
							//代表手机号码不可用
							phone_result.innerText = result.message;
						}
					}
				});
			}

		}
	</script>
</head>
<body>
	<h1>注册界面</h1>
	<form action="">
		用户名:<input type="text" id="username"><span id="username_result"></span><br>

		邮箱:<input type="text" id="email"><span id="email_result"></span><br>

		手机号码:<input type="text" id="phone"><span id="phone_result"></span>
	</form>
</body>
</html>

不要忘记了,三个php文件和之前一样,没有变化。

提示出现这种错误:Uncaught SyntaxError: Unexpected identifier,一般都是JS对象中少加了一个","号。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xupengboo

你的鼓励将是我创作最大的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值