zoukankan      html  css  js  c++  java
  • 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状态码  

    页面调试信息


      

     

        

  • 相关阅读:
    Javascript基础
    Dao习题
    构建良好的Windows程序
    初始Windows程序
    ADO.NET访问数据库
    连接查询和分组查询
    [leetcode]126. Word Ladder II单词接龙II
    [leetcode]155. Min Stack最小栈
    [leetcode]796. Rotate String旋转字串
    [leetcode]460. LFU Cache最低频率缓存
  • 原文地址:https://www.cnblogs.com/lxc116317/p/9383649.html
Copyright © 2011-2022 走看看