最近做了一个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. iOS 多语言的切换

    一.添加应用程序需要支持的国际语言 二.新建一个Localizable.strings文件,作为多语言对应的词典,存储多种语言 三.在Localizable.strings的对应文件以键值对的形式配置 ...

  2. Windows Azure Virtual Machine 之用程序控制Azure VM

    我们在很多时候可能会需要用程序来控制VM的创建,删除工作. 而在这些工作之中,用程序创建一个VM将会是一个非常复杂的过程,因为他涉及到很多步骤. 具体步骤如下 1 创建一个Hosted cloud s ...

  3. .net与数据库知识点

    <%服务器方法;%> (调用服务器方法,要写;) <=%服务器方法%> (有返回值输出,不能写;) public ActionResult Index(int id = 0) ...

  4. Redmine插件

    1.redmine_customize_core_fields可以对自带字段进行设置,看起来很不错,2016年6月23日上线,安装失败, 看来测试不完整.redmine_issue_field_vis ...

  5. MVC2,MVC3,MVC4和MVC5的不同

    现在MVC的技术日趋成熟,面对着不同版本的MVC大家不免有所迷惑 -- 它们之间有什么不同呢?下面我把我搜集的信息汇总一下,以便大家能更好的认识不同版本MVC的功能,也便于自己查阅. View Eng ...

  6. 【GO】GO语言学习笔记一

    a.为何学习GO语言? 从个人角度来看,第一是被GO语言传说中的那样超高的开发效率和运行效率所吸引:第二是GO语言在语言层面支持并发,这在现在的编程业务中是很方便的:第三是由于前两点,我觉得以后GO会 ...

  7. 我的Android第五章

    今天我们来讲一下Android四大组件中的activity的生命周期, 首先我们可以看一张activity的生命周期的图解看一下 关于Activity的生命周期,有以下几个要注意的点: 1.最开始进入 ...

  8. error: could not read CFBundleIdentifier from Info.plist (null)解决方法之一

    出现这种错误的原因可能很多,以下是我遇到的一种情况: 项目移植到新的环境 编译报错:  error: could not read CFBundleIdentifier from Info.plist ...

  9. Android多媒体--MediaCodec 中文API文档

    *由于工作需要,需要利用MediaCodec实现Playback及Transcode等功能,故在学习过程中翻译了Google官方的MediaCodec API文档,由于作者水平限制,文中难免有错误和不 ...

  10. RabbitMQ 入门 Helloworld

    1.介绍 RabbitMQ 是信息传输的中间者.本质上,他从生产者(producers)接收消息,转发这些消息给消费者(consumers).换句话说,他能够按根据你指定的规则进行消息转发.缓冲.和持 ...