学习一门新技术不外乎掌握四个点(what、how、where、why)!
一、什么是AJAX?(what)
首先要了解什么是同步?什么是异步的问题。
同步就是当浏览器提交请求到服务器时,服务器必须要响应浏览器,这样浏览器才能继续发送请求。简单来说就是请求1-响应1-请求2-响应2。
异步是当浏览器提交请求到服务器后,浏览器还未收到服务器响应之前,浏览器还能继续发送请求。不管服务器是否响应信息。请求1-请求2-响应1-响应2。
AJAX是Asychronous JavaScript And Xml缩写。就是浏览器和服务器进行交互的时候,浏览器可以不必刷新整个页面,实现局部页面与服务器进行异步通讯的技术。
简单来说,AJAX是局部刷新的异步通讯技术。注意:AJAX只是一种编程模式,并不是新的编程语言!
二、为什么要用AJAX?(why)
1.让浏览器不需要经常加载大量的静态数据,减轻浏览器的负担。
2.改善了用户对web页面的体验效果。
三、JAX适合用在什么地方(where)AJAX不用来传递大量数据,而只用来传递少量数据,在用户的体验上更加人性化。
AJAX是一个和服务器无关的技术,即服务器可使用:JavaEE,.NET,PHP,。。。这些技术都可以。
AJAX只管向服务器发送请求,同时只管接收服务器的HTML或XML或JSON载体响应。
服务端不能使用转发或重定向到web页面,因为这样会起浏览器全面刷新。
即只能以“流”的方式响应给浏览器。
AJAX不用来传递大量数据,而只用来传递少量数据,在用户的体验上更加人性化。
AJAX是一个和服务器无关的技术,即服务器可使用:JavaEE,.NET,PHP,。。。这些技术都可以。
AJAX只管向服务器发送请求,同时只管接收服务器的HTML或XML或JSON载体响应。
服务端不能使用转发或重定向到web页面,因为这样会起浏览器全面刷新。
即只能以“流”的方式响应给浏览器。
AJAX不用来传递大量数据,而只用来传递少量数据,在用户的体验上更加人性化。
AJAX是一个和服务器无关的技术,即服务器可使用:JavaEE,.NET,PHP,。。。这些技术都可以。
AJAX只管向服务器发送请求,同时只管接收服务器的HTML或XML或JSON载体响应。
服务端不能使用转发或重定向到web页面,因为这样会起浏览器全面刷新。
即只能以“流”的方式响应给浏览器。
四、AJAX开发步骤(怎么用AJAX how)
1.创建AJAX异步对象。例如:var ajax=createAJAX();
2.准备发送异步请求。例如 ajax.open(method,url);参数method表示请求方式是GET或者POST,如果是GET,无需设置AJAX请求头,如果是POST提交,必须设置AJAX请求头,例如:
ajax.setRequestHeader();
3.发送请求体中的数据到服务器。例如:ajax.send();这里如果是GET提交,请求体内容为null,需要在url地址后面加上传递的参数。如果是POST提交,需要设置请求体参数。例如var content=”key=value&key=value”;
4.AJAX异步对象不断的监听服务器的状态变化(状态码0,1,2,3,4),例如:ajax.onreadystatechange()=function(){}后面跟一个匿名函数。
5.在匿名函数中进行操作,在异步对象中获取服务器传递参数,通过DOM规则,用js代码来操作web页面。
注意:所有浏览器中都内置了异步对象,在默认情况下,该异步对象并没有创建出来。需要我们自己创建。
创建AJAX异步对象(XMLHttpRequest对象)的代码如下:
<script type="text/javascript">
//创建AJAX异步对象
function createAJAX(){
var ajax = null;
try{
//如果IE5=IE12的话
ajax = new ActiveXObject("microsoft.xmlhttp");
}catch(e1){
try{
//如果是非IE的话
ajax = new XMLHttpRequest();
}catch(e2){
alert("你的浏览器中不支持异步对象");
}
}
return ajax;
}
</script>
五、AJAX工作原理
简单来说就是浏览器将原始请求发送到AJAX异步对象中(XMLHttpRequest对象),然后异步对象经过包装后,以http协议的方式发送给服务器,服务器通过业务操作,以响应的方式返回给AJAX异步对象,然后在显示数据到浏览器中。
六、AJAX的实际应用
首先通过一个普通的显示当前时间的例子来引入AJAX。
JS+Servlet技术来实现同步方式显示当前时间的案例。
思路 设计一个input提交按钮 请求提交到服务器,服务器响应数据到浏览器
显示当前时间:${requestScope.nowTime } <br/>
<input type="button" value="同步方式显示"><p/>
其他信息文本<br/>
其他信息文本<br/>
其他信息文本<br/>其他信息文本<br/>其他信息文本<br/>
<script type="text/javascript">
var inputElement=document.getElementsByTagName("input")[0];
inputElement.onclick=function(){
var url="${pageContext.request.contextPath}/TimeServlet?time="+new Date().getTime();
window.location.href=url;
}
</script>
/**
* 显示当前时间
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String nowTime = sdf.format(new Date());
request.setAttribute("nowTime", nowTime);
//转发
request.getRequestDispatcher("/js03_time.jsp").forward(request, response);
}
可以看出当整个点击提交按钮时,整个页面加载到历史记录中,页面重新加载所有的数据。
缺点:当只需要局部刷新一个页面时,其他部分没必要跟着加载一遍。造成浏览器加载负担。
可改进的地方:让无需变化的大量数据,原封不动,不用缓存到历史栏中,无需全部刷新,只刷新某些需要变化的数据区域,这就用到AJAX技术。
运用AJAX+Servlet改进上面的代码。
<script type="text/javascript">
document.getElementById("buttonID").onclick=function(){
//1创建AJAX异步对象
var ajax = createAJAX();
//2准备发送请求
var method="GET";
var url="${pageContext.request.contextPath}/AJAXTimeServlet?id="+new Date().getTime();
ajax.open(method,url);
//3设置请求头 默认是get方式提交(忽略)
//4发送请求体到服务器
ajax.send(null);
//--------等待服务器响应 编写servlet
//5异步对象监听服务器响应的状态码
ajax.onreadystatechange=function(){
if(ajax.readyState==4){
if(ajax.status==200){
//从ajax异步对象中获取响应数据
var nowTime=ajax.responseText;
//将结果按照dom规则,添加到web页面指定位置
var spanElement=document.getElementById("spanTime");
spanElement.innerHTML=nowTime;
}
}
}
}
</script>
(2)应用二、检查用户名是否已存在数据库中
在注册页面中,我们经常会填写用户名。
用异步方式的优点: 光标离开用户名文本框之后立即提交到服务器进行查询,提醒用户。避免用户填写所有信息提交后再进行修改用户名。提高效率。
AJAX+Servlet技术:
用户名:<input type="text" id="userNameID" maxlength="10">
<span id="resSpan"></span><span id="msgID"></span>
<script type="text/javascript">
//光标失去焦点事件
document.getElementById("userNameID").onblur=function(){
//获取表单数据
var userName = this.value;
//文字提示的span标签
var msgSpan =document.getElementById("msgID");
//创建img标签
var imgElement=document.createElement("img");
//定位插入图片span标签 设置属性
var spanElement =document.getElementById("resSpan");
msgSpan.innerHTML="";
if(userName==""){
msgSpan.innerHTML="用户名不能为空";
//设置img标签属性 图片路径 大小
imgElement.src="img/MsgError.gif";
imgElement.style.width="12px";
imgElement.style.height="12px";
//清空数据
spanElement.innerHTML="";
//加入图片
spanElement.appendChild(imgElement);
}else{
//1.创建AJAX异步对象
var ajax = createAJAX();
//2.异步对象准备发送请求
var method="POST";
var url="${pageContext.request.contextPath}/UserServlet?id="+new Date().getTime();
ajax.open(method,url);
//3.如果是POST提交 设置请求头
ajax.setRequestHeader("content-type","application/x-www-form-urlencoded");
//4.发送请求体到服务器
var context="userName="+userName;
ajax.send(context);
//---------------等待服务器
//5异步对象监听服务器响应的状态码
ajax.onreadystatechange= function(){
//满足条件
if(ajax.readyState==4){
if(ajax.status==200){
//获取服务器数据
var tip=ajax.responseText;
if(tip=="img/MsgError.gif"){
msgSpan.innerHTML="用户名已存在";
}
//设置img标签属性 图片路径 大小
imgElement.src=tip;
imgElement.style.width="12px";
imgElement.style.height="12px";
//清空数据
spanElement.innerHTML="";
//加入图片
spanElement.appendChild(imgElement);
}
}
}
}
}
</script>
// 获取表单提交参数
request.setCharacterEncoding("utf-8");
String userName = request.getParameter("userName");
String tip="img/MsgSent.gif";
//从数据库中判断
if("zhangsan".equals(userName)){
tip="img/MsgError.gif";
}
//输出流
response.setContentType("text/html;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.write(tip);
pw.flush();
pw.close();
这里没有用到JDBC技术,只是模拟了一下查询数据库操作。
注意:如果采用GET提交方式 需要进行url编码
//对汉字进行UTF-8(U8)的编码; username = encodeURI(username); //加到url后面
(3)应用三、基于XML,以POST方式,完成省份-城市二级下拉联动
当点击省份下拉列表时,自动更新城市列表。
<select id="provinceID" name="province" style="width:90px">
<option>选择省份</option>
<option>山东</option>
<option>湖南</option>
</select>
<select id="cityID" name="city" style="width:90px">
<option>选择城市</option>
</select>
<script type="text/javascript">
//获取select省份标签 添加事件
document.getElementById("provinceID").onchange=function(){
//清空城市下拉框里的内容 只保留第一个
var cityElement=document.getElementById("cityID");
cityElement.options.length=1;
//获取选中option的索引 从0开始
var index=this.selectedIndex;
//获取option标签的内容
var province =this[index].innerHTML;
if(province !="选择省份"){
//1创建ajax异步对象
var ajax = createAJAX();
//2准备发送请求
var method="POST";
Var url="${pageContext.request.contextPath}/ProvinceServlet?id="+new Date().getTime();
ajax.open(method,url);
//3如果是POST提交设置请求头
ajax.setRequestHeader("content-type","application/x-www-form-urlencoded");
//4发送请求体数据到服务器
var content="province="+province;
ajax.send(content);
//--------------------等待服务器响应
//5异步对象不断的监听服务器发送的状态码
ajax.onreadystatechange = function(){
if(ajax.readyState == 4){
if(ajax.status==200){
//从异步对象中获取服务器响应的xml文档
var xmlDocument = ajax.responseXML;
//按照DOM规则,解析XML文档
var cityElementArray = xmlDocument.getElementsByTagName("city");
//遍历city数组
var size = cityElementArray.length;
for(var i=0;i<size;i++){
//获取city标签体内的内容
var city=cityElementArray[i].firstChild.nodeValue;
//创建option对象
var cityOption = document.createElement("option");
//设置cityOption
cityOption.innerHTML=city;
//把option标签添加到select中
cityElement.appendChild(cityOption);
}
}
}
}
}
}
</script>
//获取数据
request.setCharacterEncoding("utf-8");
String province=request.getParameter("province");
System.out.println(province);
//告诉AJAX异步对象 服务器采用XML方式响应数据
response.setContentType("text/xml;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.write("<?xml version='1.0' encoding='UTF-8'?>");
pw.write("<root>");
if("山东".equals(province)){
pw.write("<city>济南</city>");
pw.write("<city>青岛</city>");
pw.write("<city>菏泽</city>");
}else if("湖南".equals(province)){
pw.write("<city>长沙</city>");
pw.write("<city>株洲</city>");
pw.write("<city>湘潭</city>");
pw.write("<city>岳阳</city>");
}
pw.write("</root>");
pw.flush();
pw.close();
System.out.println("传输完成");
这里也没有用到JDBC技术,只是模拟了一下查询数据库操作。