zoukankan      html  css  js  c++  java
  • 关于 XMLHttpRequest对象的onreadyStateChange方法

    最近做了一个Ajax的demo,前台用HTML+javascript,后台用一个servlet来响应,流程如下:

    页面点击链接事件,由js捕获,生成一个请求到后台,servlet处理后给出响应信息,并显示在页面上。

    问题是,页面无法获取到servlet的响应信息。

    初始代码

    index.html

    <!DOCTYPE html>
    <html>
    <head>
        <title>Test H2</title>
        <style>
            #result{
                position:absolute;
                left:50px;
                top:300px;
            }
        </style>
        <!-- <script type="text/javascript" src="js/jquery-1.11.1.js"></script> -->
        <script>
            function handle(url){
                // Fetch the data, HERE i just give some dummy data
                var username = "joshua";
                var query = "query_test";
                var feature = url;
                var click_type = "clc_test";
                var rank = 1;
                var page_number = 1;
                var paras = "?query="+query+"&username="+username+"&feature="+feature+
                            "&click_type="+click_type+"&rank="+rank+"&page_number="+page_number;
                // transfer this data to servlet to save
                var xmlhttp;
                // code for IE7+, Firefox, Chrome, Opera, Safari
                if(window.XMLHttpRequest){
                    xmlhttp = new XMLHttpRequest;
                // code for IE6, IE5
                }else{
                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                }
                xmlhttp.open("POST","/WebDemo_H2/AjaxServlet"+paras+"&tip="+Math.random(),true);
                xmlhttp.send();
            document.getElementById("result").innerHTML = xmlhttp.responseText;
            }
        </script>
    </head>
    <body>
        <aside style="margin:10px;">
            <div>
                <p style="font-weight:bold;">Main Testing Page</p>
                <a href="index.html">Back</a>
            </div>
            <div style="height:20px"></div>
            <div>
                <a href="javascript:handle('test1.html')">test link 1</a><br/>
                <a href="javascript:handle('test2.html')">test link 2</a><br/>
                <a href="javascript:handle('test3.html')">test link 3</a>
            </div>
        </aside>
        <button onclick="">Clear Data</button>
        <div id="result">
        </div>
    </body>
    </html>

    Servlet:

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    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 AjaxServlet extends HttpServlet {
    
        public Connection conn = null;
    
        public void init() {
            try {
                Class.forName("org.h2.Driver");
                conn = DriverManager.getConnection(
                        "jdbc:h2:C:/Users/zhoum18/H2Test/db/test", "sa", "");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public void service(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
                request.setCharacterEncoding("GBK");
                response.setContentType("text/html;charset=GBK");
            // get the parameters
            try {
                PrintWriter out = response.getWriter();
                String userName = request.getParameter("username");
                String query = request.getParameter("query");
                String feature = request.getParameter("feature");
                String click_type = request.getParameter("click_type");
                String rank = request.getParameter("rank");
                String page_number = request.getParameter("page_number");
                String sql = "INSERT INTO CLICK_TRACKING SELECT ?,?,?,?,?,?";
                PreparedStatement pstmt = conn.prepareStatement(sql);
                pstmt.setString(1, query);
                pstmt.setString(2, userName);
                pstmt.setString(3, feature);
                pstmt.setString(4, click_type);
                pstmt.setInt(5, Integer.parseInt(rank));
                pstmt.setInt(6, Integer.parseInt(page_number));
                pstmt.executeUpdate();
                conn.commit();
    
                sql = "select feature,count(*) as num  from click_tracking group by feature";
                pstmt = conn.prepareStatement(sql);
                ResultSet rs = pstmt.executeQuery();
                out.println("<table border='1'>");
                out.println("<tr>");
                out.println("<td>Link</td>");
                out.println("<td>Click Times</td>");
                out.println("</tr>");
                while (rs.next()) {
                    out.println("<tr>");
                    out.println("<td>" + rs.getString("feature") + "</td>");
                    out.println("<td>" + rs.getString("num") + "</td>");
                    out.println("</tr>");
                }
                out.println("</table>");
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public void destroy() {
            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception e) {
                }
            }
        }
    }

    可以看到在servlet中用PrintWriter对象返回了建立table的HTML语句,按照逻辑,应该在页面上打印出table的内容跟应有的值;

    结果是,xmlhttp.responseText方法返回的值始终为空,没有任何值返回,用chrome浏览器调试,发现HTTP请求是有响应的,而且response tab里面有值:

    经过代码查看,发现xmlhttp对象的readystate始终为1.

    修改了下页面js的代码,将原有的写入改成了以下代码:

                xmlhttp.open("POST","/WebDemo_H2/AjaxServlet"+paras+"&tip="+Math.random(),true);
                xmlhttp.onreadystatechange = function(){
                    if (xmlhttp.readyState == 4) {
                        document.getElementById("result").innerHTML = xmlhttp.responseText;
                    }
                }
                xmlhttp.send();

    成功显示出response的内容。

    结论:

    页面发送出请求后,往往无法得知什么时候才能完成这个请求并获得回应,所以要使用一个事件机制来捕获请求完成的状态。

    XmlHttpRequest对象有一个方法,onreadystatechange这个函数实现这一个功能。

    类似于回调函数,在readystate改变时,这个方法可以指定一个函数来判断和处理,比如上面的代码:

    xmlhttp.onreadystatechange = function(){

      // 这里面的就是当readystate改变时,处理事件的代码,在我的例子中,判断了当readyState等于4的时候,再捕获相应的信息。

    }

    readyState的不同值,代表了不同的状态:

    0:尚未初始化
    1:正在加载
    2:加载完毕
    3:正在处理
    4:处理完毕

    当其变为4, 就可以访问从服务器返回的数据了。

    另附http请求相应代码

    200 请求成功
    202 请求被接受但处理未完成
    400 错误请求
    404 请求资源未找到
    500 内部服务器错误
  • 相关阅读:
    docker下用keepalived+Haproxy实现高可用负载均衡集群
    Centos 7 搭建蓝鲸V4.1.16社区版
    IDEA中Thrift插件配置
    idea打包java可执行jar包
    CentOS7 docker.repo 用阿里云Docker Yum源
    linux 配置maven环境变量
    Linux中修改docker镜像源及安装docker
    Spring-boot和Spring-Cloud遇到的问题
    IntelliJ Idea 常用快捷键列表
    Invocation of destroy method failed on bean with name ‘XXXX’
  • 原文地址:https://www.cnblogs.com/ChewApple/p/3829124.html
Copyright © 2011-2022 走看看