最近做了一个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 内部服务器错误

关于 XMLHttpRequest对象的onreadyStateChange方法的更多相关文章

  1. javascript XMLHttpRequest 对象的open() 方法参数说明

    下文是从w3c上摘录下来的,其中参数 method 说明的很简短,不是很理解,所以又找了些资料作为补充.文中带括号部分. XMLHttpRequest.open() 初始化 HTTP 请求参数 语法o ...

  2. $.ajax通用格式&&XMLHttpRequest对象属性和方法

    $.ajax({ url: "", type: "POST", async: false, cache:false, //默认true data: {}, da ...

  3. JS创建Ajax的XMLHttpRequest对象的通用方法

    function createXMLHttpRequest() { var request = false; if(window.XMLHttpRequest) { request = new XML ...

  4. Ajax学习(三)——XMLHttpRequest对象的五步使使用方法

        Ajax的核心技术是XMLHttpRequest对象,它能够在不向server提交整个页面的情况下.实现局部更新网页.通过这个对象,Ajax能够像桌面应用程序那样仅仅与server进行数据层的 ...

  5. XMLHttpRequest对象的属性与方法

    XMLHttpRequest对象是Ajax的核心,它有很多属性和方法.1,readyState属性当一个XMLHttpRequest对象被创立后,readyState属性标示了当前对象处于什么状态,可 ...

  6. PHP. 02®. Ajax异步处理、常见的响应状态、XMLHttpRequest对象及API、ajax的get/post方法、

    异步对象 a)创建异步对象 b)设置请求的url等参数 c)  发送请求 d)注册时间 e)在注册的事件中获取返回的内容并修改页面显示的内容 布尔类型不能直接用echo输出 常见的响应状态 Ajax概 ...

  7. Ajax中的XMLHttpRequest对象详解

    XMLHttpRequest对象是Ajax技术的核心.在Internet Explorer 5中,XMLHttpRequest对象以ActiveX对象引入,被称之为XMLHTTP,它是一种支持异步请求 ...

  8. javascript XMLHttpRequest对象全面剖析

    转载:http://www.jb51.net/article/23175.htm 一. 引言 异步JavaScript与XML(AJAX)是一个专用术语,用于实现在客户端脚本与服务器之间的数据交互过程 ...

  9. 全面剖析XMLHttpRequest对象

    XMLHttpRequest对象是当今所有AJAX和Web 2.0应用程序的技术基础.尽管软件经销商和开源社团现在都在提供各种AJAX框架以进一步简化XMLHttpRequest对象的使用:但是,我们 ...

随机推荐

  1. 最常用的截取函数有left,right,substring

    最常用的截取函数有left,right,substring 1.LEFT ( character_expression , integer_expression ) 返回从字符串左边开始指定个数的字符 ...

  2. 在 ASP.NET MVC 中使用 HTTPS (SSL/TLS) -- 学习

    在 ASP.NET MVC 中使用 HTTPS (SSL/TLS) IS 7如何实现http重定向https HTTPS 升级指南

  3. mysql 慢查询日志切割

  4. Oracle EBS R12 (12.1.3) Installation Linux(64 bit)

    Oracle EBS R12 (12.1.3) Installation Linux(64 bit) Contents Objective. 3 1 Download & Unzip. 3 D ...

  5. 用STM32CubeMX创建FreeRTOS项目

    1. 目标, PG13,PG14双线程双闪灯. 2. 测试平台 stm32f429i-disco keil v5.13.0.0 CubeMx 4.8.0 3. 步骤 3.1 打开cube, PG13, ...

  6. java动态代理原理

    我们经常会用到Java的动态代理技术, 虽然会使用, 但是自己对其中的原理却不是很了解.比如代理对象是如何产生的, InvocationHandler的invoke方法是如何调用的?今天就来深究下Ja ...

  7. Android开发——搭建最新版本的Android开发环境

    http://www.cnblogs.com/smyhvae/p/3788534.html http://www.cnblogs.com/xdp-gacl/p/4322165.html http:// ...

  8. this的用法

    因为循环是非常快的,我们手动点击的时候,for循环已经循环完了.如果在循环里面添加点击事件,点击事件的i的值就是循环结果的那个值,而不是对应的循环的值,此时,我们就需要用到this   来实现  点击 ...

  9. [原创]Keil uVision4 安装破解

    Keil uVision4 安装没什么特别的,跟一般Windows软件安装方法相同,这里不再赘述. 安装完成界面如下图,未破解之前,点击编译,下载等选项都会出现未响应提示,软件会卡死.下面进行软件破解 ...

  10. hightcharts 3d 堆积图下钻

    图片效果 ***************代码部分****************************************************** <!doctype html> ...