关于 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 内部服务器错误
关于 XMLHttpRequest对象的onreadyStateChange方法的更多相关文章
- javascript XMLHttpRequest 对象的open() 方法参数说明
下文是从w3c上摘录下来的,其中参数 method 说明的很简短,不是很理解,所以又找了些资料作为补充.文中带括号部分. XMLHttpRequest.open() 初始化 HTTP 请求参数 语法o ...
- $.ajax通用格式&&XMLHttpRequest对象属性和方法
$.ajax({ url: "", type: "POST", async: false, cache:false, //默认true data: {}, da ...
- JS创建Ajax的XMLHttpRequest对象的通用方法
function createXMLHttpRequest() { var request = false; if(window.XMLHttpRequest) { request = new XML ...
- Ajax学习(三)——XMLHttpRequest对象的五步使使用方法
Ajax的核心技术是XMLHttpRequest对象,它能够在不向server提交整个页面的情况下.实现局部更新网页.通过这个对象,Ajax能够像桌面应用程序那样仅仅与server进行数据层的 ...
- XMLHttpRequest对象的属性与方法
XMLHttpRequest对象是Ajax的核心,它有很多属性和方法.1,readyState属性当一个XMLHttpRequest对象被创立后,readyState属性标示了当前对象处于什么状态,可 ...
- PHP. 02®. Ajax异步处理、常见的响应状态、XMLHttpRequest对象及API、ajax的get/post方法、
异步对象 a)创建异步对象 b)设置请求的url等参数 c) 发送请求 d)注册时间 e)在注册的事件中获取返回的内容并修改页面显示的内容 布尔类型不能直接用echo输出 常见的响应状态 Ajax概 ...
- Ajax中的XMLHttpRequest对象详解
XMLHttpRequest对象是Ajax技术的核心.在Internet Explorer 5中,XMLHttpRequest对象以ActiveX对象引入,被称之为XMLHTTP,它是一种支持异步请求 ...
- javascript XMLHttpRequest对象全面剖析
转载:http://www.jb51.net/article/23175.htm 一. 引言 异步JavaScript与XML(AJAX)是一个专用术语,用于实现在客户端脚本与服务器之间的数据交互过程 ...
- 全面剖析XMLHttpRequest对象
XMLHttpRequest对象是当今所有AJAX和Web 2.0应用程序的技术基础.尽管软件经销商和开源社团现在都在提供各种AJAX框架以进一步简化XMLHttpRequest对象的使用:但是,我们 ...
随机推荐
- iOS 多语言的切换
一.添加应用程序需要支持的国际语言 二.新建一个Localizable.strings文件,作为多语言对应的词典,存储多种语言 三.在Localizable.strings的对应文件以键值对的形式配置 ...
- Windows Azure Virtual Machine 之用程序控制Azure VM
我们在很多时候可能会需要用程序来控制VM的创建,删除工作. 而在这些工作之中,用程序创建一个VM将会是一个非常复杂的过程,因为他涉及到很多步骤. 具体步骤如下 1 创建一个Hosted cloud s ...
- .net与数据库知识点
<%服务器方法;%> (调用服务器方法,要写;) <=%服务器方法%> (有返回值输出,不能写;) public ActionResult Index(int id = 0) ...
- Redmine插件
1.redmine_customize_core_fields可以对自带字段进行设置,看起来很不错,2016年6月23日上线,安装失败, 看来测试不完整.redmine_issue_field_vis ...
- MVC2,MVC3,MVC4和MVC5的不同
现在MVC的技术日趋成熟,面对着不同版本的MVC大家不免有所迷惑 -- 它们之间有什么不同呢?下面我把我搜集的信息汇总一下,以便大家能更好的认识不同版本MVC的功能,也便于自己查阅. View Eng ...
- 【GO】GO语言学习笔记一
a.为何学习GO语言? 从个人角度来看,第一是被GO语言传说中的那样超高的开发效率和运行效率所吸引:第二是GO语言在语言层面支持并发,这在现在的编程业务中是很方便的:第三是由于前两点,我觉得以后GO会 ...
- 我的Android第五章
今天我们来讲一下Android四大组件中的activity的生命周期, 首先我们可以看一张activity的生命周期的图解看一下 关于Activity的生命周期,有以下几个要注意的点: 1.最开始进入 ...
- error: could not read CFBundleIdentifier from Info.plist (null)解决方法之一
出现这种错误的原因可能很多,以下是我遇到的一种情况: 项目移植到新的环境 编译报错: error: could not read CFBundleIdentifier from Info.plist ...
- Android多媒体--MediaCodec 中文API文档
*由于工作需要,需要利用MediaCodec实现Playback及Transcode等功能,故在学习过程中翻译了Google官方的MediaCodec API文档,由于作者水平限制,文中难免有错误和不 ...
- RabbitMQ 入门 Helloworld
1.介绍 RabbitMQ 是信息传输的中间者.本质上,他从生产者(producers)接收消息,转发这些消息给消费者(consumers).换句话说,他能够按根据你指定的规则进行消息转发.缓冲.和持 ...