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();
        }
    }
}
View Code

这是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>
View Code

这是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("出错了!");
            }
                }


}
View Code

      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("出错了!");
            }
                }


}
View Code

附上HTTP状态码  

页面调试信息

 


  

 

 

    

 

posted @ 2018-07-28 22:10  李贤春  阅读(656)  评论(0编辑  收藏  举报