Ajax简介
- Ajax是一种网页开发技术(Asynchronous +Javascript+XML)异步Javascript和XML
- Ajax是异步交互,局部刷新
- Ajax能减少服务器压力
- Ajax能提高客户体验
Ajax交互与传统交互的比较
- 传统交互:页面整体刷新,服务器压力大,用户体验不好
- Ajax交互:局部刷新,服务器压力小,用户体验好。
XMLHttpRequest对象的创建
所有现代浏览器均支持XMLHttpRequest对象(IE5,IE6使用ActiveXObject) XMLHttpRequest用于在后台与服务器交换数据,这意味着可以不用重新加载整个页面的情况下,对网页的某一部分进行更新 |
XMLHttpRequest的方法
open(method,url,async) | method规定请求的类型(post,get),url请求的地址,async是否以异步方式处理请求(true异步,false同步) |
send(string) | 将请求发送给服务器,string仅适用于post请求 |
setRequestHeader(header,value) | 向请求头部添加HTTP头,header规定头的名称,value规定头的值 |
|
|
|
|
|
|
|
|
GET和POST的区别
get更简单更快,而且在大部分情况下都能使用,但存在长度限制。
post请求可以使用缓存文件(更新服务器上的文件或数据库),向服务器发送大量数据(post没有数据量限制),发送包含未知字符的用户输入时更加的安全可靠。
测试
创建test01.jsp
<script type="text/javascript"> function loadName() { var xmlHttp; if (window.XMLHttpRequest) { //如果是现代浏览器,则直接创建 xmlHttp = new XMLHttpRequest(); }else{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); //IE5,IE6老款浏览器 } xmlHttp.open("get","getAjaxName",true); xmlHttp.send(); } </script> </head> <body> <div style="text-align: center;"> <div> <input type="button" onclick="loadName()" value="Ajax获取" /> <input type="text" id="name" name="name" /> </div> </div> </body> |
编写GetAjaxServlet.java用于后台处理
public class GetAjaxServlet extends HttpServlet{
private static final long serialVersionUID = 1133414213854778480L;
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("ok"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("ajax返回的文本"); out.flush(); out.close(); } } |
编写web.xml
<servlet> <servlet-name>getAjaxNameServlet</servlet-name> <servlet-class>com.kingsoft.servlet.GetAjaxServlet</servlet-class> </servlet>
<servlet-mapping> <servlet-name>getAjaxNameServlet</servlet-name> <url-pattern>/getAjaxName</url-pattern> </servlet-mapping> |
测试test01.jsp传递参数并以get方式
<script type="text/javascript"> function loadName() { var xmlHttp; if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); }else{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlHttp.open("get","getAjaxName?name=jack&age=13",true); xmlHttp.send(); } </script> |
GetAjaxServlet.java接收参数
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("ok"); String name = request.getParameter("name"); String age = request.getParameter("age"); System.out.println("name:"+name+" age:"+age); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("ajax返回的文本"); out.flush(); out.close(); } |
使用Firefox浏览器显示测试结果
单击F12进入开发者模式,单击控制台,测试按钮单击事件
单击参数可以查看参数是否传递成功,单击相应可以查看是否得到GetAjaxServlet的返回相应 |
这时还可以尝试将xmlHttp的请求类型修改为post方式
<script type="text/javascript"> function loadName() { var xmlHttp; if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); }else{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlHttp.open("post","getAjaxName?name=jack&age=13",true); xmlHttp.send(); } </script> 可以在控制台看到请求方式为post
但是这种方式还是以明文的方式传递,十分不安全 |
这时只需要修改前台页面test01.jsp
<script type="text/javascript"> function loadName() { var xmlHttp; if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); }else{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlHttp.open("post","getAjaxName",true); //以post方式传递参数 xmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");//向请求头部添加HTTP头,"Content-type"规定头的名称,"application/x-www-form-urlencoded"规定头的值 xmlHttp.send("name=jack&age=11"); //将请求发送给服务器,string仅适用于post请求 } </script> 测试结果如下图所示
发出请求方式为POST,而且getAjaxName后面没有明文参数,参数是以post数据包的形式传递 |
XMLHttpRequest对象相应服务器
onreadystatechange事件
当请求被发送到服务器时,我们需要执行一些基于相应的任务,每当readyState改变时就会触发onreadystatechange事件,readyState属性存有XMLHttpRequest的状态信息。
这个存有XMLHttpRequest的状态,从0到4发生变化。
0:请求未初始化
1:服务器连接已建立
2:请求已接收
3:请求处理中
4:请求已完成,响应已经就绪
state有两种状态
200:“OK”
404:未找到指定的页面
在onreadystatechange事件中,我们规定当服务器相应已做好被处理的准备是所执行的任务。
如需获得来自服务器的相应,请使用XMLHttpRequest对象的responseText或responseXML属性。
responseText :获得字符串形式的相应数据
responseXML:获取XML形式的相应数据(了解即可)
<script type="text/javascript"> function loadName() { var xmlHttp; if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); }else{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } alert("readState状态:"+xmlHttp.readyState+";status状态:"+xmlHttp.status); xmlHttp.onreadystatechange = function(){ //重写服务器准备好后执行的任务 alert("readState状态:"+xmlHttp.readyState+";status状态:"+xmlHttp.status); if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ alert(xmlHttp.responseText); document.getElementById("name").value=xmlHttp.responseText; } } //ajax以post形式发送请求 xmlHttp.open("post","getAjaxName",true); xmlHttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlHttp.send("name=jack&age=11"); } </script> |
Json
Json:Javascript对象表示法(javascript Object Notation) Json是存储和交换文本信息的语法,类似XML Json比XML更小,更快,更易解析 |
Json格式语法
JSON 对象 { "name":"张三" , "age":22}
JSON 数组 { "student": [ { "name":"张三" , "age":22 }, { "name":"李四" , "age":23 }, { "name":"王五" , "age":24 } ] } JSON 嵌套 { "student": [ { "name":"张三" , "age":22 ,"score":{"chinese":90,"math":100,"english":80} }, { "name":"李四" , "age":23 ,"score":{"chinese":70,"math":90, "english":90} }, { "name":"王五" , "age":24 ,"score":{"chinese":80,"math":60, "english":90} } ] } 把Json 串换成Json 对象 var dataObj=eval("("+data+")");//转换为json 对象 |
Ajax&Json的简单交互
<script type="text/javascript"> function loadInfo() { var xmlHttp; if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); }else{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlHttp.onreadystatechange = function(){ if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ var dataObj = eval("("+xmlHttp.responseText+")"); //转换为Json对象 document.getElementById("name").value=dataObj.name; //赋值 document.getElementById("age").value=dataObj.age; } } xmlHttp.open("get","getAjaxInfo",true); xmlHttp.send(); } </script> </head> <body> <div style="text-align: center;"> <div> <input type="button" onclick="loadInfo()" value="Ajax获取" /> 姓名:<input type="text" id="name" name="name" /> 年龄:<input type="text" id="age" name="age"/> </div> </div> </body> |
引入需要使用的json-lib的jar包
加入到lib目录中,便可自动加入工程 |
编写GetAjaxInfoServlet.java
public class GetAjaxInfoServlet extends HttpServlet {
private static final long serialVersionUID = 4132138798529697880L;
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { this.doPost(request, response); }
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); JSONObject resultJson = new JSONObject();//以操作对象的方式操作json resultJson.put("name", "zhangsan"); resultJson.put("age", 22); out.println(resultJson); out.flush(); out.close(); } } |
修改web.xml
<servlet> <servlet-name>getAjaxInfoServlet</servlet-name> <servlet-class>com.kingsoft.servlet.GetAjaxInfoServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>getAjaxInfoServlet</servlet-name> <url-pattern>/getAjaxInfo</url-pattern> </servlet-mapping> |
从后台获取JSON串,在前台展示
创建ajax1.jsp
<script type="text/javascript"> function loadInfo2() { var xmlHttp; if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); }else{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlHttp.onreadystatechange = function(){ if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ var dataObj = eval("("+xmlHttp.responseText+")"); alert(xmlHttp.responseText); var st = document.getElementById("studentTable"); alert(dataObj.students.length); var newTr; //行 var newTd0; //第一列 var newTd1; //第二列 var newTd2; var newTd3; var newTd4; for(var i=0;i<dataObj.students.length;i++){ var student = dataObj.students[i]; newTr = st.insertRow(); //插入行 newTd0 = newTr.insertCell(); // 在行中插入第列 newTd1 = newTr.insertCell(); newTd2 = newTr.insertCell(); newTd3 = newTr.insertCell(); newTd4 = newTr.insertCell();
newTd0.innerHTML=student.name; newTd1.innerHTML=student.age; newTd2.innerHTML=student.score.chinese; newTd3.innerHTML=student.score.math; newTd4.innerHTML=student.score.english; } } } //xmlHttp.open("get","getAjaxInfo?action=jsonArray",true); xmlHttp.open("get","getAjaxInfo?action=jsonNested",true); //根据action传入值,在后台选择进入的方法 xmlHttp.send(); } </script> </head> <body> <div style="text-align: center;"> <div style="margin-top:20px;"> <input type="button" onclick="loadInfo2()" value="Ajax获取学生"><br><br> <table id="studentTable" align="center" border="1px" align="center" cellpadding="0px" cellspacing="0px"> <tr> <th width="100">姓名</th> <th width="100">年龄</th> <th width="100">语文</th> <th width="100">数学</th> <th width="100">英语</th> </tr> </table> </div> </div> </body> |
修改GetAjaxInfoServlet.java
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ response.setContentType("text/html;charset=utf-8"); String action = request.getParameter("action"); if("jsonObject".equals(action)) { this.getJsonObject(request, response); }else if("jsonArray".equals(action)) { this.getJsonArray(request, response); }else if("jsonNested".equals(action)) { //根据前台传入action的值选择执行的方法 this.getJsonNested(request, response); } }
private void getJsonNested(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ PrintWriter out = response.getWriter(); JSONObject resultJson = new JSONObject(); //合成后传给Json JSONArray jsonArray = new JSONArray(); //用于合成数组,传给resultJson
JSONObject obj1 = new JSONObject(); obj1.put("name", "张三"); obj1.put("age", 22); JSONObject score1 = new JSONObject(); score1.put("chinese", 90); score1.put("math", 100); score1.put("english", 80); obj1.put("score", score1);
JSONObject obj2 = new JSONObject(); obj2.put("name", "李四"); obj2.put("age", 21); JSONObject score2 = new JSONObject(); score2.put("chinese", 93); score2.put("math", 90); score2.put("english", 92); obj2.put("score", score2);
JSONObject obj3 = new JSONObject(); obj3.put("name", "王五"); obj3.put("age", 20); JSONObject score3 = new JSONObject(); score3.put("chinese", 94); score3.put("math", 89); score3.put("english", 83); obj3.put("score", score3);
jsonArray.add(obj1); jsonArray.add(obj2); jsonArray.add(obj3);
resultJson.put("students", jsonArray); out.println(resultJson); System.out.println("jsonarray"); out.flush(); out.close();
}
|
编写web.xml
<servlet> <servlet-name>getAjaxInfoServlet</servlet-name> <servlet-class>com.kingsoft.servlet.GetAjaxInfoServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>getAjaxInfoServlet</servlet-name> <url-pattern>/getAjaxInfo</url-pattern> </servlet-mapping> |
用户注册时验证功能
创建login.jsp页面
<script type="text/javascript"> function checkUser() { var userName = document.getElementById("userName").value; var xmlHttp; if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); }else{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlHttp.onreadystatechange = function(){ if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ alert("得到参数"); var dataObj = eval("("+xmlHttp.responseText+")"); if(dataObj.exist){ document.getElementById("tip").innerHTML="<img src='images/no.png'/> 该用户名已存在"; }else{ document.getElementById("tip").innerHTML="<img src='images/ok.png'/>"; } } } xmlHttp.open("get","getAjaxInfo?action=checkUserName&userName="+userName,true); xmlHttp.send(); alert("传递参数"); }</script> </head> <body> <table> <tr> <th>用户注册</th> </tr> <tr> <td>用户名:</td> <td> <input type="text" name="userName" id="userName" onblur="checkUser()"> <font id="tip"></font> </td> </tr> <tr> <td>密码:</td> <td><input type="password" name="password" id="password"></td> </tr> <tr> <td>确认密码:</td> <td><input type="password" name="repassword" id="repassword"></td> </tr> <tr> <td><input type="submit" value="注册"></td> <td><input type="button" value="重置"></td> </tr> </table> </body> |
验证的方法中的流程说明
|
在WebContent文件夹下创建images文件夹,拷入no.png,ok.png图标
创建GetAjaxInfoServlet.java
public class GetAjaxInfoServlet extends HttpServlet {
private static final long serialVersionUID = 4132138798529697880L;
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { this.doPost(request, response); }
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); String action = request.getParameter("action"); if ("checkUserName".equals(action)) { //如果action带入的值是checkUserName,则执行 this.checkUserName(request, response); } }
private void checkUserName(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { String userName = request.getParameter("userName"); //获取用户名 PrintWriter out = response.getWriter(); JSONObject resultJson = new JSONObject(); if("wanghuan".equals(userName)) { //模拟,如果用户名等于wanghuan resultJson.put("exist", Boolean.TRUE); }else { resultJson.put("exist", Boolean.FALSE); } out.println(resultJson); out.flush(); out.close(); }
} |
修改web.xml文件
<servlet> <servlet-name>getAjaxInfoServlet</servlet-name> <servlet-class>com.kingsoft.servlet.GetAjaxInfoServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>getAjaxInfoServlet</servlet-name> <url-pattern>/getAjaxInfo</url-pattern> </servlet-mapping> |
测试使用ajax&json实现省,市下拉框的联动
创建ajax.jsp
<script type="text/javascript"> function loadInfo() { var shengId = document.getElementById("sheng").value; var shi = document.getElementById("shi"); shi.options.length=0; //每次选择省份时将市的内容清空 var xmlHttp; if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); }else{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlHttp.onreadystatechange = function(){ if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ var dataObj = eval("("+xmlHttp.responseText+")"); for(var i=0;i<dataObj.row.length;i++){ var obj = dataObj.row[i]; shi.options.add(new Option(obj.text,obj.id));//先内容,后id } } } xmlHttp.open("get","getAjaxInfo?action=change&shengId="+shengId,true); xmlHttp.send(); } </script> </head> <body> 省<select id="sheng" onchange="loadInfo()"> <option value="1">辽宁省</option> <option value="2">吉林省</option> <option value="3">黑龙江省</option> </select> 市<select id="shi"></select> </body> |
创建GetAjaxInfoServlet.java
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); String action = request.getParameter("action"); if ("checkUserName".equals(action)) { this.checkUserName(request, response); } else if ("change".equals(action)) { //action带的参数是change this.change(request, response); } }
private void change(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String shengId = request.getParameter("shengId"); PrintWriter out = response.getWriter(); JSONObject resultJson = new JSONObject(); JSONArray jsonArray = new JSONArray(); JSONObject temp = null; switch (Integer.parseInt(shengId)) { case 1: { temp = new JSONObject(); temp.put("id", 1); temp.put("text", "沈阳市"); jsonArray.add(temp);
temp = new JSONObject(); temp.put("id", 2); temp.put("text", "大连市"); jsonArray.add(temp);
temp = new JSONObject(); temp.put("id", 3); temp.put("text", "鞍山市"); jsonArray.add(temp); break; } case 2: { temp = new JSONObject(); temp.put("id", 4); temp.put("text", "吉林市"); jsonArray.add(temp);
temp = new JSONObject(); temp.put("id", 5); temp.put("text", "长春市"); jsonArray.add(temp);
temp = new JSONObject(); temp.put("id", 6); temp.put("text", "四平市"); jsonArray.add(temp); break; } case 3: { temp = new JSONObject(); temp.put("id", 7); temp.put("text", "哈尔滨市"); jsonArray.add(temp);
temp = new JSONObject(); temp.put("id", 8); temp.put("text", "大庆市"); jsonArray.add(temp);
temp = new JSONObject(); temp.put("id", 9); temp.put("text", "鹤岗市"); jsonArray.add(temp); break; }
} resultJson.put("row", jsonArray); out.println(resultJson); out.flush(); out.close(); } |
修改web.xml
<servlet> <servlet-name>getAjaxInfoServlet</servlet-name> <servlet-class>com.kingsoft.servlet.GetAjaxInfoServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>getAjaxInfoServlet</servlet-name> <url-pattern>/getAjaxInfo</url-pattern> </servlet-mapping> |