原生ajax
1、ajax是什么?
*asynchronous javascript and xml:异步的js和xml
*它能使用js访问服务器,而且是异步访问!
*服务器给客户端的响应一般是整个页面,一个html完整页面!但是在ajax中因为是局部刷新,那么服务器就不用再响应整个页面!而只是数据。
>text:纯文本
>xml:还可以
>json:它是js提供的数据交互格式,它在ajax中最受欢迎
2、异步交互和同步交互
*同步
>发一个请求,就要等待服务器的响应结束,然后才能发第二个请求!中间的这段时间就是一个字“卡”
>刷新的是整个页面
*异步
>发一个请求后,无需等待服务器的响应,然后就可以发第二个请求!
>可以使用js来接受服务器的响应,然后使用js来局部刷新!
3、ajax的应用场景
*百度的搜索框
*校验用户名是否被注册
4、ajax的优缺点
优点:
*异步交互:增强了用户的体验!
*性能:因为服务器无需再响应整个页面,只需要响应部分内容,所以服务器的压力减轻了
缺点:
*ajax 不能应用在所有场景
*ajax无端地增多了对服务器的访问次数,给服务器带来了压力
5、ajax发送异步请求(四步操作)
1、第一步(得到XMLHttpRequest)
*ajax其实只需要学习一个对象:XMLHttpRequest:如果掌握了它,就掌握了ajax
*得到XMLHttpRequest
>大多数浏览器都支持: var xmlHttp=new XMLHttpRequest();
>IE6.0: var xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
>IE5.5以更早版本的IE:var xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
*编写创建XMLHttpRequest对象的函数 我原来的方式是获取浏览器版本,现在发现好像这种使用异常的方式真取巧,还显得有点专业!
function createXMLHttpRequest(){
try{
return new XMLHttpRequest();
}catch(e){
try{
return new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try{
return new ActiveXObject("Microsoft.XMLHTTP")
}catch(e){
alert("哥们,你用的什么浏览器啊!")
throw e;
}
}
}
}
2.第二步(打开与服务器的连接)
*xmlHttp.open():用来打开与服务器的连接,它需要三个参数:
>请求的方式:可以是GET或POST
>请求的URL:指定服务器端资源,例如/8-8-9/AServlet
>请求是否异步:如果为true表示发送异步请求,否则同步请求!
*xmlHttp.open("GET","/8-8-9/AServlet",true);
3、第三步(发送请求)
*xmlHttp.send(null):如果不给可能会造成部分浏览器无法发送!
>参数:就是请求内容!如果是Get请求,必须给出null。post请求例如这种模样:xmlHttp.send(username=zhangSan&password=123)
4、第四部()
*在xmlHttp对象的一个事件上注册监听器:onreadystatechange
*xmlHttp对象一共有5个状态:
0:刚创建还没有调用open()方法
1:请求开始,调用了open()方法,但还没有调用send()方法
2:调用完了send()方法了
3:服务器已经开始响应,但不表示响应结束了!
4:服务器响应结束!(通常我们只关心最后这个状态!!!)
*得到xmlHttp对象的状态
>var state=xmlHttp.readyState;//可能是0、1、2、3、4
*得到服务器的响应的状态码
>var status=xmlHttp.status;//例如为200、404、500
*得到服务器响应的内容
>var content=xmlHttp.responseText;//得到服务器的响应的文本内容
>var content=xmlHttp.responseXML;//得到服务器响应的xml响应的内容,它是Document对象了
xmlHttp.onreadystatechange=function(){//当xmlHttp的状态变化,5种状态都会调用本方法
if(xmlHttp.readyState==4 && xmlHttp.readyState==200){//双重判断,判断是否为4状态而且是否为200
var text=xmlHttp.responseText;//得到响应的文本内容
}
}
例子:
使用get方式的demo:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'ajax1.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript"> window.onload=function(){ var btn=document.getElementById("btn"); btn.onclick=function(){ /* ajax四步操作,得到服务器响应,把响应结果显示到h1元素中 */ /* 1、得到异步对象 */ var xmlHttp=createXMLHttpRequest(); /* 2、打开与服务器的连接 */ /* 指定请求方式 * 指定请求的url *指定是否为异步请求 * *这里使用jstl标签给出的解释是:jsp其实展示的是html,也就是说其实脚本是写在html内的,tomcat服务器先将jsp转换成servlet,一些元素变成html代码,里面的标签就会先变成代码,所以我们发送的url不是现在显示的标签字符串 */ xmlHttp.open("GET","<c:url value='/AServlet' />",true); /* 3、发送请求 */ xmlHttp.send(null);//get请求没有请求体也要给出null,否则firefox可能出现问题 /*4、给异步对象添加监听*/ xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState==4 && xmlHttp.status==200){ //获取服务器的响应结果 var text=xmlHttp.responseText; var h1=document.getElementById("h1"); h1.innerHTML=text; } } }; }; function createXMLHttpRequest(){ try{ return new XMLHttpRequest(); }catch(e){ try{ return new ActiveXObject("Msxml2.XMLHTTP");//IE6.0 }catch(e){ try{ return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5以及更早版本 }catch(e){ alert("哥们,你用的什么浏览器啊!"); throw e; } } } } </script> </head> <body> <button id="btn">点击这里</button> <h1 id="h1"></h1> </body> </html>
post方式与get方式基本一致,多了设置一个头文件,还有在send()这一栏发送参数:
<script type="text/javascript"> window.onload=function(){ var btn=document.getElementById("btn"); btn.onclick=function(){ /* ajax四步操作,得到服务器响应,把响应结果显示到h1元素中 */ /* 1、得到异步对象 */ var xmlHttp=createXMLHttpRequest(); /* 2、打开与服务器的连接 */ /* 指定请求方式 * 指定请求的url *指定是否为异步请求 * *这里使用jstl标签给出的解释是:jsp其实展示的是html,也就是说其实脚本是写在html内的,tomcat服务器先将jsp转换成servlet,一些元素变成html代码,里面的标签就会先变成代码,所以我们发送的url不是现在显示的标签字符串 */ /**** 修改open方法,指定请求方式为post ***/ xmlHttp.open("POST","<c:url value='/AServlet' />",true); /***** 设置请求头 ***********/ xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); /* 3、发送请求 */ xmlHttp.send("username=张三");//get请求没有请求体也要给出null,否则firefox可能出现问题 /*4、给异步对象添加监听*/ xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState==4 && xmlHttp.status==200){ //获取服务器的响应结果 var text=xmlHttp.responseText; var h1=document.getElementById("h1"); h1.innerHTML=text; } } }; }; function createXMLHttpRequest(){ try{ return new XMLHttpRequest(); }catch(e){ try{ return new ActiveXObject("Msxml2.XMLHTTP");//IE6.0 }catch(e){ try{ return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5以及更早版本 }catch(e){ alert("哥们,你用的什么浏览器啊!"); throw e; } } } } </script>
简单的验证用户是否被注册:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'ajax3.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <script type="text/javascript"> window.onload=function(){ var uname=document.getElementsByName("username")[0]; uname.onblur=function(){ /* 1、获取xmlHttpRequest对象 */ var xmlHttp=createXMLHttpRequest(); /* 2.打开连接 . 三个参数:请求方式,url,是否异步 */ xmlHttp.open("POST","<c:url value='/ValidateUsernameServlet'/>",true); /* 3.传递参数 */ /**** Post方式需要先设置响应头 *****/ xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xmlHttp.send("username="+uname.value); /* 4.监听响应 */ xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState==4 && xmlHttp.status==200){ var text=xmlHttp.responseText; var sp=document.getElementById("sp1"); if(text==1){ sp.innerHTML="该用户名已经被注册"; }else{ sp.innerHTML=""; } } } } } function createXMLHttpRequest(){ try{ return new XMLHttpRequest(); }catch(e){ try{ return new ActiveXObject("Msxml2.XMLHTTP");//IE6 }catch(e){ try{ return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5以前 }catch(e){ alert("哥们,你这是什么浏览器啊!"); throw e; } } } } </script> </head> <body> <h1>演示用户名是否被注册</h1> <form action="<c:url value='/AServlet' />" method="post"> 用户名:<input type="text" name="username"/><span id="sp1"></span><br/> 密码:<input type="password" name="pasword"/><br/> 性别:<input type="radio" name="sex" value="nan">男 <input type="radio" name="sex" value="nv">女<br/> 邮箱:<input type="text" name="email"/><br/> <input type="submit" value="注册"/> </form> </body> </html> public class ValidateUsernameServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8"); String username=request.getParameter("username"); if(username.equals("itcast")){ response.getWriter().print(1); }else{ response.getWriter().print(0); } } }
返回的是XML的例子:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'ajax1.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript"> window.onload=function(){ var btn=document.getElementById("btn"); btn.onclick=function(){ /* ajax四步操作,得到服务器响应,把响应结果显示到h1元素中 */ /* 1、得到异步对象 */ var xmlHttp=createXMLHttpRequest(); /* 2、打开与服务器的连接 */ /* 指定请求方式 * 指定请求的url *指定是否为异步请求 * *这里使用jstl标签给出的解释是:jsp其实展示的是html,也就是说其实脚本是写在html内的,tomcat服务器先将jsp转换成servlet,一些元素变成html代码,里面的标签就会先变成代码,所以我们发送的url不是现在显示的标签字符串 */ xmlHttp.open("GET","<c:url value='/BServlet' />",true); /* 3、发送请求 */ xmlHttp.send(null);//get请求没有请求体也要给出null,否则firefox可能出现问题 /*4、给异步对象添加监听*/ xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState==4 && xmlHttp.status==200){ //获取服务器的响应结果 var doc=xmlHttp.responseXML; //查询文档下名为student的所有元素,得到数据 var eleArr=doc.getElementsByTagName("student")[0]; var number=eleArr.getAttribute("number"); /* var number=eleArr.getAttribute("number"); var name=eleArr.getElementsByTagName("name")[0].innerHTML;//IE支持 var age=eleArr.getElementsByTagName("age")[0].innerHTML;//IE支持 */ /* var name=eleArr.getElementsByTagName("name")[0].text;//IE支持,谷歌得到的是undefined var age=eleArr.getElementsByTagName("age")[0].text;//IE支持 */ var name=eleArr.getElementsByTagName("name")[0].firstChild.nodeValue; var age=eleArr.getElementsByTagName("age")[0].firstChild.nodeValue; /* var name=eleArr.getElementsByTagName("name")[0].textContent; //非IE var age=eleArr.getElementsByTagName("age")[0].textContent;//非IE */ var text=number+", "+name+", "+age; document.getElementById("h1").innerHTML=text; } } }; }; function createXMLHttpRequest(){ try{ return new XMLHttpRequest(); }catch(e){ try{ return new ActiveXObject("Msxml2.XMLHTTP");//IE6.0 }catch(e){ try{ return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5以及更早版本 }catch(e){ alert("哥们,你用的什么浏览器啊!"); throw e; } } } } </script> </head> <body> <button id="btn">点击这里</button> <h1 id="h1"></h1> </body> </html> import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String xml="<students>"+ "<student number='ITCAST_1001'>"+ "<name>zhangSan</name>"+ "<age>18</age>"+ "</student>"+ "</students>"; response.setContentType("text/xml;charset=utf-8"); response.getWriter().print(xml); } }
级联城市菜单的例子:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'ajax5.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <script type="text/javascript"> /* *1.在文档加载完毕时发送请求,得到所有省份名称,显示在<select name="province">中 *2.在选择了新的省份时,删除原来的city下拉列表的第一项外所有子元素,发送请求去cityServlet,参数省份名字,根据返回来的xml给option赋值 */ window.onload=function(){ var province=document.getElementsByName("province")[0]; var city=document.getElementsByName("city")[0]; function loadProvince(){ var xmlHttp=createXMLHttpRequest(); xmlHttp.open("GET","<c:url value='ProvinceServlet'/>",true); xmlHttp.send(null); xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState==4 && xmlHttp.status==200){ var text=xmlHttp.responseText; var pArr=text.split(","); for(var i=0;i<pArr.length;i++){ var eleNode=document.createElement("option"); var ele_text =document.createTextNode(pArr[i]); /* 下拉列表的value属性可以不设置,默认是下拉列表选项内容的文本值 */ eleNode.appendChild(ele_text); province.appendChild(eleNode); } } }; } loadProvince(); province.onchange=function(){ // 获取其所有子元素 var optionEleList = city.getElementsByTagName("option"); // 循环遍历每个option元素,然后在citySelect中移除 while(optionEleList.length > 1) {//子元素的个数如果大于1就循环,等于1就不循环了! city.removeChild(optionEleList[1]);//总是删除1下标,因为1删除了,2就变成1了! } var pv=province.value; if(pv=="===请选择省==="){ return; } var xmlHttp=createXMLHttpRequest(); xmlHttp.open("POST","<c:url value='/CityServlet'/>",true); xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xmlHttp.send("province="+pv); xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState==4 && xmlHttp.status==200){ var doc=xmlHttp.responseXML; var citys=doc.getElementsByTagName("city"); for(var i=0;i<citys.length;i++){ var str=citys[i].firstChild.nodeValue; var eleNode=document.createElement("option"); var ele_text =document.createTextNode(str); /* 下拉列表的value属性可以不设置,默认是下拉列表选项内容的文本值 */ eleNode.appendChild(ele_text); city.appendChild(eleNode); } } }; }; } function createXMLHttpRequest(){ try{ return new XMLHttpRequest(); }catch(e){ try{ return new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ try{ return new ActiveXObject("Microsoft.XMLHTTP"); }catch(e){ alert("兄弟,你用的什么浏览器啊"); throw e; } } } } </script> </head> <body> <h1>省市联动</h1> <select name="province"> <option>===请选择省===</option> </select> <select name="city"> <option>===请选择市===</option> </select> </body> </html> public class CityServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/xml;charset=utf-8"); SAXReader reader=new SAXReader(); Document document=null; String pro=request.getParameter("province"); Element d = null; try { document=reader.read(this.getServletContext().getRealPath("/xml/china.xml")); List<Element> eles=document.getRootElement().elements("province"); for(int i=0;i<eles.size();i++){ Element e=eles.get(i); String str=e.attributeValue("name"); if(str.equals(pro)){ d=e; break; } } } catch (DocumentException e) { e.printStackTrace(); } response.getWriter().print(d.asXML()); } public class ProvinceServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); SAXReader reader=new SAXReader(); Document document=null; StringBuffer provinces = new StringBuffer(); try { document=reader.read(this.getServletContext().getRealPath("/xml/china.xml")); List<Element> eles=document.getRootElement().elements("province"); for(int i=0;i<eles.size();i++){ Element e=eles.get(i); String str=e.attributeValue("name"); if(i==0){ provinces.append(str); }else{ provinces.append(","+str); } } } catch (DocumentException e) { e.printStackTrace(); } response.getWriter().print(provinces.toString()); } }