ajax深入理解异步请求过程及原理
AJAX异步请求原理和过程
整体思维
先定义一个servlet代码,写出web.xml文件;接着编写html文件,写好后在页面调试,在按钮标签那关联onclick事件;最后编写js文件,编写事件与html文件进行关联,并通过xmlHttpRequest对象与servlet文件进行交互,完成ajax异步请求
具体过程
1.创建XMLHttpRequest对象。AJAX 的要点是 XMLHttpRequest 对象。不同的浏览器创建 XMLHttpRequest 对象的方法是有差异的。IE浏览器使用 ActiveXObject,而其他的浏览器使用名为 XMLHttpRequest 的 JavaScript 内建对象。
首先声明一个保存 XMLHttpRequest 对象的 xmlHttp 变量。 然后使用 XMLHttp=new XMLHttpRequest() 来创建此对象。这条语句针对 Firefox、Opera 以及 Safari 浏览器。假如失败,则尝试针对 Internet Explorer 6.0+ 的 xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"),假如也不成功,则尝试针对 Internet Explorer 5.5+ 的 xmlHttp=new ActiveXObject("Microsoft.XMLHTTP")。 假如这三种方法都不起作用,那么这个用户所使用的浏览器已经太过时了,他或她会看到一个声明此浏览器不支持 AJAX 的提示。
2.注册回调函数
onreadystatechange:请求状态改变的事件触发器(readyState变化时会调用此方法);
3.设置连接信息
xmlhttp.open("GET","AjaxServlet?userName"+name,true),
第一个参数代表http的请求方式,支持所有的http的请求方式,主要使用get和post;第二个参数表示请求的URL地址,get方式请求的参数也在url中;第三个参数表示采用异步还是同步方式交互,true表示异步。
这是servlet(服务器端的代码)
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /* * XML的数据 * */ @WebServlet(name = "AjaxXmlServlet") public class AjaxXmlServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try{ // 修改点1. 必须是text/xml response.setContentType("text/xml;charset=UTF-8"); request.setCharacterEncoding("UTF-8"); PrintWriter out=response.getWriter(); String dataName=request.getParameter("userName"); // 修改点2.返回的数据需要拼装成xml格式 StringBuilder builder=new StringBuilder(); builder.append("<message>"); if(dataName==null||dataName.length()==0){ builder.append("用户名不能为空").append("</message>"); }else { String name=dataName; if(name.equals("lxc")){ builder.append("用户名["+name+"]已存在,请更换").append("</message>"); }else { builder.append("用户名["+name+"]未被注册,可以使用").append("</message>"); } out.println(builder.toString()); System.out.println(builder.toString()); } }catch (Exception e){ e.printStackTrace(); } } }
这是html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>李贤春</title> <script type="text/javascript" src="jslib/verifyXml.js"></script> </head> <body> ajax下进行用户校验的实例,请输入用户名:<br/> <input type="text" id="username"/> <input type="button" value="校验" onclick="verify()"/> <div id="result"></div> </body> </html>
这是js代码
//用户名校验的方法 /* 这里将要使用XMLHttpRequest对象来进行Ajax的异步数据交互 * */ var xmlhttp; function verify() { var name=document.getElementById("username").value; //1.创建XMLHttpRequest对象 /* * 这是XMLHttpRequest对象中最复杂的一步 * 需要针对IE及其他浏览器建立这个对象的不同方式些不同的代码 * */ if(window.XMLHttpRequest){ //针对Firefox,Mozillar,Opera,Safari,IE7+ xmlhttp=new XMLHttpRequest(); // 针对某些特定版本的mozillar浏览器的BUG进行修正 if(xmlhttp.overrideMimeType){ xmlhttp.overrideMimeType("text/xml"); } }else if(window.ActiveXObject){ // 针对IE6,IE5.5,IE5 /* * 两个可以用于创建XMLHttpRequest对象的控件名称,保存在一个js的数组中 * */ var activexName=["MSXML2.XMLHTTP","Microsoft.XMLHTTP"]; for (var i=0;i<activexName.length;i++) { try{ // 去除一个控件名进行创建,若创建成功就终止循环 // 若创建失败,回抛出异常,然后可以继续循环,继续尝试创建 xmlhttp=new ActiveXObject(activexName[i]); break; }catch (e) { } } } // 确认XMLHttpRequest对象创建成功 if(!xmlhttp){ alert("XMLHttpRequest对象创建失败!!"); return; } /*else { alert(xmlhttp); }*/ //2.注册回调函数 xmlhttp.onreadystatechange=callback; //3.设置连接信息,即请求url地址 /* * 第一个参数代表http的请求方式,支持所有的http的请求方式,主要使用get和post * 第二个参数表示请求的URL地址,get方式请求的参数也在url中 * 第三个参数表示采用异步还是同步方式交互,true表示异步 * */ xmlhttp.open("GET","AjaxXmlServlet?userName="+name,true); /* //post方式请求的代码 xmlhttp.open("POST","AjaxServlet",true); //post方式需要自己设置http的请求头 xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //post方式发送数据 xmlhttp.send("name="+name);*/ //4.发送数据,开始和服务器端进行交互 /* * 同步方式下,send这句话会在服务器端数据返回后才执行完 * 异步方式下,send这句话会立即完成执行 * */ xmlhttp.send(null); } function callback() { // 5.接收响应数据 // 判断对象的状态是否交互完成 if(xmlhttp.readyState==4){ if(xmlhttp.status==200){ //使用responseXml的方式来接收xml数据对象的dom方式 var domObj=xmlhttp.responseXML; if(domObj){ //<message>1644484<message/> //dom中利用getElementByTagName可以根据标签名获取文本内容 var messageNodes=domObj.getElementsByTagName("message"); if(messageNodes.length>0){ //获取message节点中的内容 //获取文本内容的第一个子节点 var textNode=messageNodes[0].firstChild; //获取第一个子节点中的值 var responseMessage=textNode.nodeValue; // 将数据显示在页面上 // 通过dom的方式找到div标签所对应的元素节点 var divNode=document.getElementById("result"); // 设置元素节点中的html内容*/ divNode.innerHTML=responseMessage; }else { alert("xml数据格式错误,数据文本内容为:"+xmlhttp.responseText); } } else { alert("xml数据格式错误,数据文本内容为:"+xmlhttp.responseText); } } else { alert("出错了!"); } } }
4.发送数据,开始和服务器端进行交互
xmlhttp.send(null);
send()向服务器发出请求,如果采用异步方式,该方法会立即返回。 Content可以不指定,其内容可以是DOM对象,输入流或是字符串。
在调用回调函数之前先理清一下顺序:
使用ajax发送请求一般的操作顺序是,先open、然后赋值onreadystatechange=...、最后send。
open只是初始化,做好准备发送。send才是发送请求。onreadystatechange是告诉xmlhttp当他的state发生改变的时候执行
重点:
readyState在生成xmlHttp时为0, 在 XMLHttpRequest.open时即改变,open会触发onreadystatechange事件的。
open放在onreadystatechange之前,会比放在onreadystatechange之后少执行一次onreadystatechange事件。readyState 属性存有服务器响应的状态信息。每
当 readyState 改变时,onreadystatechange 函数就会被执行。
即xmlhttp的onreadystatechange要放在send前面是为了给xmlHttp的readyState变化绑定一个监听事件
下面是 readyState 属性可能的值:
状态 描述
0 请求未初始化(在调用 open() 之前)
1 请求已提出(调用 send() 之前)
2 请求已发送(这里通常可以从响应得到内容头部)
3 请求处理中(响应中通常有部分数据可用,但是服务器还没有完成响应)
4 请求已完成(可以访问服务器响应并使用它)
5.回调函数
function callback() { // 5.接收响应数据 // 判断对象的状态是否交互完成 if(xmlhttp.readyState==4){ // alert("nhao"); if(xmlhttp.status==200){ //使用responseXml的方式来接收xml数据对象的dom方式 var domObj=xmlhttp.responseXML; if(domObj){ //<message>1644484<message/> //dom中利用getElementByTagName可以根据标签名获取文本内容 var messageNodes=domObj.getElementsByTagName("message"); if(messageNodes.length>0){ //获取message节点中的内容 //获取文本内容的第一个子节点 var textNode=messageNodes[0].firstChild; //获取第一个子节点中的值 var responseMessage=textNode.nodeValue; // 将数据显示在页面上 // 通过dom的方式找到div标签所对应的元素节点 var divNode=document.getElementById("result"); // 设置元素节点中的html内容*/ divNode.innerHTML=responseMessage; }else { alert("xml数据格式错误,数据文本内容为:"+xmlhttp.responseText); } } else { alert("xml数据格式错误,数据文本内容为:"+xmlhttp.responseText); } } else { alert("出错了!"); } } }
附上HTTP状态码
页面调试信息