初识--Ajax & Json
1,AJAX是一种进行页面局部异步刷新技术。
用AJAX向服务器发送请求和获得服务器返回的数据并更新到页面中。
不是刷新整个页面,而是在HTML页面中使用JavaScript创建XMLHTTPRequest对象向服务器发出请求以及获得返回的数据。
常见例子:帖子评论、视频下的评论,我们提交评论以后不会有整个HTML页面的刷新,不会有视频的中断。
2,我们借助Nvelocity模板引擎写一个一般处理程序,实现评论中常见的 [赞、踩] 功能。
Demo 下载 (1,Demo中的视频需自行添加 2,方便排版Demo中用了Bootstrap, 可参考http://www.bootcss.com/)
我们发现,每次点击 赞或踩 页面都重新刷新了一次,正在播放的视频也重新播放了。
3,我们再用Ajax实现点击显示点赞次数。
新建CommentByAjax.html,页面中给按钮 “赞” 添加 onclick方法 , onclick方法中 通过javascript创建XMLHTTPRequest对象向服务器端的一般处理程序请求处理结果。
处理结果返回到html页面并显示,这样整个过程没有刷新页面,只是通过XMLHTTPRequest对象请求了点赞次数,实现了局部刷新。
效果如下:连续点赞 页面显示点赞次数递增,视频没有中断或者重播。
步骤:A, 新建CommnetByAJAX.html页面,并添加 javascript 方法创建XMLHTTPRequest对象请求服务器
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <!-- Bootstrap --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> <script type="text/javascript"> function AddZan() { var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); //创建XMLHTTP对象,考虑兼容性 xmlhttp.open("POST", "ZanCaiCount.ashx?" + "Action=Zan", true); //“准备”向服务器的ZanCaiCount.ashx发出Post请求(GET可能会有缓存问题)。这里还没有发出请求 xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4) //readyState == 4 表示服务器返回完成数据了。之前可能会经历2(请求已发送,正在处理中)、3(响应中已有部分数据可用了,但是服务器还没有完成响应的生成) { if (xmlhttp.status == 200) //如果状态码为200则是成功 { document.getElementById("ZanNum").innerHTML = xmlhttp.responseText; } else { alert("AJAX服务器返回错误!"); } } } //不要以为if (xmlhttp.readyState == 4) {在send之前执行!!!! xmlhttp.send(); //这时才开始发送请求 //发出请求后不等服务器返回数据,就继续向下执行,所以不会阻塞,界面就不卡了,这就是AJAX中“A”的含义“异步”。试着在ashx加一句Thread.Sleep(3000); } </script> </head> <body> <form action="CountComments.ashx" method="post"> <div class="row"> <div class="col-md-1"></div> <div class="col-md-5"> <video src="./Surface%20Pro%203.mp4" autoplay="autoplay" width="320" height="240" controls="controls" /> </div> <div class="col-md-6"></div> </div> <div class="row"> <div class="col-md-1"></div> <div class="col-md-1"> <input type="button" name="Zan" value="赞" onclick="AddZan()" /><label id="ZanNum"></label> </div> <div class="col-md-1"> <input type="button" name="Cai" value="踩" onclick="AddCai()" /><label id="CaiNum"></label> </div> <div class="col-md-9"></div> </div> </form> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> <script src="js/bootstrap.min.js"></script> </body>
B, 添加 点赞、点踩 计算的一般处理程序: ZanCai.ashx ,接收CommentByAJAX.html传递过来的参数(Zan/Cai)计算次数,并返回
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace AjaxDemo { /// <summary> /// ZanCaiCount 的摘要说明 /// </summary> public class ZanCaiCount : IHttpHandler { private static int numZan = 0; private static int caiNum = 0; public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //根据Action参数判断是赞 还是 踩 string strAction = context.Request.QueryString["Action"]; if (strAction == "Zan") { numZan++; context.Response.Write(numZan.ToString()); //输出 } else if (strAction == "Cai") { caiNum++; context.Response.Write(caiNum.ToString()); //输出 } } public bool IsReusable { get { return false; } } } }
C, 以上完成了AJAX请求点赞次数。 整个过程主要就是 javascript方法创建XMLHTTPRequest对象向服务器请求数据,如下代码:
<script type="text/javascript"> function AddZan() { var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); //创建XMLHTTP对象,考虑兼容性 xmlhttp.open("POST", "ZanCaiCount.ashx?" + "Action=Zan", true); //“准备”向服务器的ZanCaiCount.ashx发出Post请求(GET可能会有缓存问题)。这里还没有发出请求 xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4) //readyState == 4 表示服务器返回完成数据了。之前可能会经历2(请求已发送,正在处理中)、3(响应中已有部分数据可用了,但是服务器还没有完成响应的生成) { if (xmlhttp.status == 200) //如果状态码为200则是成功 { document.getElementById("ZanNum").innerHTML = xmlhttp.responseText; } else { alert("AJAX服务器返回错误!"); } } } //不要以为if (xmlhttp.readyState == 4) {在send之前执行!!!! xmlhttp.send(); //这时才开始发送请求 //发出请求后不等服务器返回数据,就继续向下执行,所以不会阻塞,界面就不卡了,这就是AJAX中“A”的含义“异步”。试着在ashx加一句Thread.Sleep(3000); } </script>
4, 我们把上面一段JavaScript方法封装到js文件中, 方便以后调用。
步骤: A, js文件夹下添加 ajax.js
function ajax(url, onsuccess) { var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); //创建XMLHTTP对象,考虑兼容性 xmlhttp.open("POST", url, true); //“准备”向服务器的ZanCaiCount.ashx发出Post请求(GET可能会有缓存问题)。这里还没有发出请求 xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4) //readyState == 4 表示服务器返回完成数据了。之前可能会经历2(请求已发送,正在处理中)、3(响应中已有部分数据可用了,但是服务器还没有完成响应的生成) { if (xmlhttp.status == 200) //如果状态码为200则是成功 { onsuccess(xmlhttp.responseText); //document.getElementById("ZanNum").innerHTML = xmlhttp.responseText; } else { alert("AJAX服务器返回错误!"); } } } //不要以为if (xmlhttp.readyState == 4) {在send之前执行!!!! xmlhttp.send(); //这时才开始发送请求 //发出请求后不等服务器返回数据,就继续向下执行,所以不会阻塞,界面就不卡了,这就是AJAX中“A”的含义“异步”。试着在ashx加一句Thread.Sleep(3000); }
B, CommnetByAJAX.html页面添加对ajax的引用 并 实现点击 “踩”的时候显示次数
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <!-- Bootstrap --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> <script src="js/ajax.js"></script> <script type="text/javascript"> function AddZan() { var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); //创建XMLHTTP对象,考虑兼容性 xmlhttp.open("POST", "ZanCaiCount.ashx?" + "Action=Zan", true); //“准备”向服务器的ZanCaiCount.ashx发出Post请求(GET可能会有缓存问题)。这里还没有发出请求 xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4) //readyState == 4 表示服务器返回完成数据了。之前可能会经历2(请求已发送,正在处理中)、3(响应中已有部分数据可用了,但是服务器还没有完成响应的生成) { if (xmlhttp.status == 200) //如果状态码为200则是成功 { document.getElementById("ZanNum").innerHTML = xmlhttp.responseText; } else { alert("AJAX服务器返回错误!"); } } } //不要以为if (xmlhttp.readyState == 4) {在send之前执行!!!! xmlhttp.send(); //这时才开始发送请求 //发出请求后不等服务器返回数据,就继续向下执行,所以不会阻塞,界面就不卡了,这就是AJAX中“A”的含义“异步”。试着在ashx加一句Thread.Sleep(3000); } function AddCai() { ajax("ZanCaiCount.ashx?action=Cai", function (result) { document.getElementById("CaiNum").innerHTML = result }) } </script> </head> <body> <form action="CountComments.ashx" method="post"> <div class="row"> <div class="col-md-1"></div> <div class="col-md-5"> <video src="./Surface%20Pro%203.mp4" autoplay="autoplay" width="320" height="240" controls="controls" /> </div> <div class="col-md-6"></div> </div> <div class="row"> <div class="col-md-1"></div> <div class="col-md-1"> <input type="button" name="Zan" value="赞" onclick="AddZan()" /><label id="ZanNum"></label> </div> <div class="col-md-1"> <input type="button" name="Cai" value="踩" onclick="AddCai()" /><label id="CaiNum"></label> </div> <div class="col-md-9"></div> </div> </form> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> <script src="js/bootstrap.min.js"></script> </body>
点赞点踩效果如下
5, AJAX的经常用在网站新用户注册的时候,检查用户名称是否存在。
步骤: A, 添加新用户注册页面,页面中用户名文本框中添加onbluer()事件,鼠标焦点离开以后触发检查用户民是否存在
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>新用户注册</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> <script src="js/ajax.js"></script> <script type="text/javascript"> function checkIfExist() { ajax("RegCheckNewUserName.ashx?NewName=" + document.getElementById("NewName").value, function (result) { document.getElementById(ReminderInfo.innerHTML = result) }); } </script> </head> <body> <form method="post"> <div class="row"> <div class="col-md-1"></div> <div class="col-md-1">用户名:</div> <div class="col-md-2"> <input type="text" id="NewName" name="NewUserName" onblur="checkIfExist()" /> </div> <div class="col-md-4"> <label id="ReminderInfo"></label> </div> <div class="col-md-3"></div> </div> <div class="row"> <div class="col-md-1"></div> <div class="col-md-1">密码:</div> <div class="col-md-2"> <input type="password" name="pwd" /> </div> <div class="col-md-8"></div> </div> <div class="row"> <div class="col-md-1"></div> <div class="col-md-1"> <input type="submit" name="btnRegister" value="注册" /> </div> <div class="col-md-10"></div> </div> </form> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> <script src="js/bootstrap.min.js"></script> </body> </html>
B, 添加检查用户名称是否存在的一般处理程序
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace AjaxDemo { /// <summary> /// RegCheckNewUserName 的摘要说明 /// </summary> public class RegCheckNewUserName : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //检查传递过来的参数是否存在 //新建数组存储部分用户名 List<string> strExist = new List<string> { "橙子", "柚子", "西瓜", "荔枝", "苹果", "葡萄", "火龙果" }; if (string.IsNullOrEmpty(context.Request["NewName"])) { context.Response.Write("用户名为空哦,请您填写用户名"); } else { string strUserName = context.Request["NewName"].ToString(); if (strExist.Contains(strUserName)) { //已经存在 context.Response.Write("用户名已存在,请重新选择用户名"); } else { context.Response.Write("恭喜您,此用户名可以注册"); } } } public bool IsReusable { get { return false; } } } }
6, 以上我们借助AJAX进行简单的数据传输,但是我们还会有一些复杂的数据请求需要借助AJAX完成。
例如,输入员工工号以后,通过AJAX请求出来该工号对应的基本信息(姓名、性别、年龄、邮箱、电话号码、户籍、爱好等)
这样,我们请求页面传递工号参数,AJAX请求的一般处理程序页面读取相关数据以后返回,这些数据就需要一定的格式给请求页面以方便请求页面解析读取各个字段属性,这样的解析我们借助Json就会更加方便了。
7,Json,是一种轻量级的数据交换格式,方便机器进行解析和生成,同时让人们很容易的阅读和编写。Json是几乎被所有的语言支持的。
我们新建一般处理程序,输出一个数组对象,看看Json输出的格式是怎样的:
步骤:A, 新建Person类
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace AjaxDemo { public class Person { public string Name { get; set; } public string Age { get; set; } public string Gender { get; set; } public string Email { get; set; } public string Address { get; set; } } }
B, 添加JsonOutPut.ashx一般处理程序,程序中我们借助JavascriptSerializer把Person数组对象以Json格式输出
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Script.Serialization; namespace AjaxDemo { /// <summary> /// JsonOutput 的摘要说明 /// </summary> public class JsonOutput : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //定义Person对象的数组 List<Person> perList = new List<Person>(); perList.Add(new Person() { Name = "橙子", Age = "18", Gender = "M", Email = "Orange@163.com", Address = "上海" }); perList.Add(new Person() { Name = "苹果", Age = "17", Gender = "F", Email = "Apple@163.com", Address = "北京" }); perList.Add(new Person() { Name = "椰子", Age = "20", Gender = "F", Email = "CocoNut@163.com", Address = "广州" }); //以Json格式字符串把 perList进行输出 //------1,初始化一个JavaScriptSerializer对象 JavaScriptSerializer jss = new JavaScriptSerializer(); //------2,获得一个对象的Json格式 string JsonList = jss.Serialize(perList); context.Response.Write(JsonList); } public bool IsReusable { get { return false; } } } }
C, Json格式输出,这样的字符串格式就很清晰明了,方便读取
8,上面返回的Json字符串,在HTML页面中我们怎么去解析呢 ?也就是咋么去读取Name或者Age属性呢 ?
HTMl页面中就需要借助Json.Parse把Json字符串解析成对象
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <script src="js/ajax.js"></script> <script type="text/javascript"> function readjsonlist() { ajax("JsonOutput.ashx", function (result) { var pers = JSON.parse(result); for (var i = 0; i < pers.length; i++) { var p = pers[i]; alert("姓名:" + p.Name + "年龄:" + p.Age); } }); } </script> </head> <body> <input type="button" onclick="readjsonlist()" value="点击查看数组对象" /> </body> </html>
<script src="js/ajax.js"></script> <script type="text/javascript"> function readjsonlist() { ajax("JsonOutput.ashx", function (result) { var pers = JSON.parse(result); for (var i = 0; i < pers.length; i++) { var p = pers[i]; alert("姓名:" + p.Name + "年龄:" + p.Age); } }); } </script>
参考网站:Bootstrap http://www.bootcss.com/