今天学了ajax技术,特地在此写下来作为复习。
一、什么是ajax?
客户端(特指PC浏览器)与服务器,可以在【不必刷新整个浏览器】的情况下,与服务器进行异步通讯的技术 即,AJAX是一个【局部刷新】的【异步】通讯技术,
说白了就是局部刷新。
二、ajax的原理如下图
附上ajax与服务器之间的几种状态,但 4是所有浏览器都支持的的
三、ajax包含的技术如下图
四、ajax开发步骤
步一:创建ajax对象,例如:ajax = createAjax();
步二:开启异步对象:例如:ajax.open(method,url)
步三:如果是POST请求则要设置请求头,例如:ajax.setRequestHeader("content-type","application/x-www-form-urlencoded");这句话的作用是转码,如果遇到中文,将会自动转成UTF-8编码;
步四:发送请求:例如:如果是GET请求,ajax.send(null),因为GET请求的数据在请求头中就已经被发送了,即地址栏后的用?username=""
如果是POST请求,content一般写成这种形式,content = "username="+username; ajax.send(content);
步五:AJAX不断的监听服务端响应的状态变化,例如:ajax.onreadystatechange,后面写一个无名处理函数
步六:在无名处理函数中,获取AJAX的数据后,按照DOM规则,用JS语言来操作Web页面
五、ajax的应用例子,以用户登录为例,
1)使用GET方式,要注意IE浏览器,使用下面这条语句,防止IE自动缓存相同内容不刷新,
var url = "${pageContext.request.contextPath}/AjaxUserServlet?username="+username+"&time="+new Date().getTime();
jsp代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% 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>通过使用GET,POST方式来使用ajax验证用户名是否重复</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"> --> </head> <body> 用户名: <input type="text" id="username" maxlength="4"/> <span id="rsID"></span> <hr/> <!-- ajax对象 --> <script type="text/javascript"> function createAjax() { var ajax =null; try{ ajax = new ActiveXObject("microsoft.xmlhttp"); }catch(e1) { try{ ajax = new XMLHttpRequest(); }catch(e2) { alert("你的浏览器不支持AJAX异步对象"); } } return ajax; } </script> <script type="text/javascript"> document.getElementById("username").onblur = function() { var username = this.value; if(username.length == 0) { document.getElementById("rsID").innerHTML="用户名不能为空"; } else { //对汉字进行编码 username = encodeURI(username); //1)首先创建Ajax对象 var ajax = createAjax(); //2)打开连接 var method = "GET"; var url = "${pageContext.request.contextPath}/AjaxUserServlet?username="+username+"&time="+new Date().getTime(); ajax.open(method,url); //3)真正发送数据 ajax.send(null); //4)Ajax对象不断监听服务器响应的状态 ajax.onreadystatechange = function() { if(ajax.readyState == 4) { //5)响应码是200的话,从ajax对象中取出数据 if(ajax.status == 200) { var rsText = ajax.responseText; document.getElementById("rsID").innerHTML=rsText; } } } } } </script> </body> </html>
java后台代码:在ajax与java后台之间使用流来传递数据的
package cn.itcast.js.user; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AjaxUserServlet extends HttpServlet { /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); byte [] buf = username.getBytes("ISO8859-1"); username = new String(buf,"UTF-8"); String tip = "<font color=‘green‘>可以注册</font>"; if("杰克".equals(username)) { tip = "<font color=‘red‘>该用户已注册</font>"; } System.out.println(username); response.setContentType("text/html;charset=UTF-8"); PrintWriter pw = response.getWriter(); pw.write(tip); pw.flush(); pw.close(); } }
GET实现效果:
2)、POST方式实现ajax登录验证
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% 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>通过使用GET,POST方式来使用ajax验证用户名是否重复</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"> --> </head> <body> 用户名: <input type="text" id="username" maxlength="4"/> <span id="rsID"> <!-- --> </span> <hr/> <!-- 引入外部js文件 --> <script type="text/javascript" src="js/ajax.js"> </script> <script type="text/javascript"> document.getElementById("username").onblur = function() { var username = this.value; //1) var ajax = createAjax(); //2) method = "POST"; url = "${pageContext.request.contextPath}/AjaxUserServlet?time="+new Date().getTime(); ajax.open(method,url); //post方式提交要设置请求头自动将中文转换为UTF-8 ajax.setRequestHeader("content-type","application/x-www-form-urlencoded"); //3) var content = "username="+username; ajax.send(content); //on ready state change ajax.onreadystatechange = function() { if(ajax.readyState == 4) { if(ajax.status == 200) { //5) var tip = ajax.responseText; //6)创建img标签 var imgElement = document.createElement("img"); //设置img标签的src/width/height imgElement.src = tip; imgElement.style.width = "12px"; imgElement.style.height = "12px"; //定位span标签 var spanElement = document.getElementById("rsID"); //清空span标签的内容,防止重复出现图片 spanElement.innerHTML = ""; //将img标签加入到span标签 spanElement.appendChild(imgElement); } } } } </script> </body> </html>
外部js代码:
//外部js文件 function createAjax() { var ajax =null; try{ ajax = new ActiveXObject("microsoft.xmlhttp"); }catch(e1) { try{ ajax = new XMLHttpRequest(); }catch(e2) { alert("你的浏览器不支持AJAX异步对象"); } } return ajax; }
java后台代码:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); byte [] buf = username.getBytes("ISO8859-1"); username = new String(buf,"UTF-8"); String tip = "<font color=‘green‘>可以注册</font>"; if("杰克".equals(username)) { tip = "<font color=‘red‘>该用户已注册</font>"; } System.out.println(username); response.setContentType("text/html;charset=UTF-8"); PrintWriter pw = response.getWriter(); pw.write(tip); pw.flush(); pw.close(); }
PSOT实现效果:
六、除了这种方式,当然后续还会利用xml实现验证二级下拉框联动
jsp代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% 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>通过使用GET,POST方式来使用ajax验证用户名是否重复</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"> --> </head> <body> 用户名: <select id="provinceID" style="width:111px"> <option>请选择省份</option> <option>湖北</option> <option>广东</option> </select> <select id="cityID" style="width:111px"> <option>请选择城市</option> </select> <hr/> <!-- 引入外部js文件 --> <script type="text/javascript" src="js/ajax.js"> </script> <script type="text/javascript"> document.getElementById("provinceID").onchange = function() { //清除下拉列框之前的内容,第一项除外 var cityElement = document.getElementById("cityID"); cityElement.options.length = 1; //获取选中省份的名字 var index = this.selectedIndex; var optionElement = this[index]; var province = optionElement.innerHTML; //去掉提示"请选择省份" if("请选择省份" != province) { //NO1) var ajax = createAjax(); //NO2) var method = "POST"; var url = "${pageContext.request.contextPath}/ProvinceCityServlet?time="+new Date().getTime(); ajax.open(method,url); //设置请求头 ajax.setRequestHeader("content-type", "application/x-www-form-urlencoded"); //NO3) var content = "province="+province; ajax.send(content); //NO4) ajax.onreadystatechange = function() { if(ajax.readyState == 4) { if(ajax.status == 200) { //NO5)从ajax异步对象中获取服务器XML数据 var xmlDocument = ajax.responseXML; //N06)按照DOM规则,解析xml数据 var cityElementArray = xmlDocument.getElementsByTagName("city"); var size = cityElementArray.length; for(var i=0;i<size;i++) { //innerHTML只能用在html标签中 var city = cityElementArray[i].innerHTML; //<option></option> var optionElement = document.createElement("option"); //<option>深圳</option> optionElement.innerHTML = city; //<select><option>广东</option></select> //appendeChild()不会去除之前的内容 cityElement.appendChild(optionElement); } } } } } } </script> </body> </html>
外部js代码:
//外部js文件 function createAjax() { var ajax =null; try{ ajax = new ActiveXObject("microsoft.xmlhttp"); }catch(e1) { try{ ajax = new XMLHttpRequest(); }catch(e2) { alert("你的浏览器不支持AJAX异步对象"); } } return ajax; }
java代码实现
package cn.itcast.js.province; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ProvinceCityServlet extends HttpServlet { /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String province = request.getParameter("province"); System.out.println(province); String city = ""; if("广东".equals(province)) { city="<city>广州</city>"+"<city>深圳</city>"+"<city>惠州</city>"; }else if("湖北".equals(province)) { city = "<city>武汉</city>"+"<city>黄冈</city>"+"<city>宜昌</city>"; } response.setContentType("text/xml;charset=utf-8"); PrintWriter pw = response.getWriter(); pw.write("<?xml version=‘1.0‘ encoding=‘UTF-8‘?>"); pw.write("<root>"); pw.write(city); pw.write("</root>"); pw.flush(); pw.close(); } //需求实现从数据库中读取数据并添加到xml文件中 }
最后实现效果: