关于 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对象的使用:但是,我们 ...
随机推荐
- Spring学习笔记之四----基于Annotation的Spring AOP编程
你能使用@Aspect annotation将某个Java类标注为Aspect,这个Aspect类里的所有公有方法都可以成为一个Advice,Spring提供了5个Annotation去将某个方法标注 ...
- Linux内核USB驱动【转】
本文转载自:http://www.360doc.com/content/12/0321/14/8363527_196286673.shtml 注意,该文件是2.4的内核的驱动源文件,并不保证在2.6内 ...
- thinkPHP 5.0.x 使用SQLite3 进行缓存设置 Cache
1. 配置 thinkPHP cache [application/config.php] 把type设置为sqlite3(默认是小写,第一个字母不区分大小写) 把path换成db,并指定sqlite ...
- Oracle序列(Sequence)创建、使用、修改、删除
Oracle对象课程:序列(Sequence)创建.使用.修改.删除,序列(Sequence)是用来生成连续的整数数据的对象.序列常常用来作为主键中增长列,序列中的可以升序生成,也可以降序生成.创建序 ...
- 富文本编辑器TInyMCE,本地图片上传(Image Upload)
TinyMCE 官网 (类似:百度的富文本web编辑器UEditor) 第一步 下载 TinyMCE,解压后放入工程,在需要的HTML页面引入tinymce.min.js. 第二步 下载tinyMCE ...
- mongoose操作汇总。嘻嘻
MongoDb 命令查询所有数据库列表 CODE: > show dbs 如果想查看当前连接在哪个数据库下面,可以直接输入db CODE: > db Admin 想切换到test数 ...
- Python 对目录中的文件进行批量转码(GBK>UTF8)
通过python实现对文件转码,其实处理很简单: 1.打开读取文件内容到一个字符串变量中,把gbk编码文件,对字符串进行decode转换成unicode 2.然后使用encode转换成utf-8格式. ...
- Android Studio 2.0使用指南
一.下载界面.[无激活码 无序列码 无毒请放心使用][需将JAVA程序升级到1.8] 网址:http://www.android-studio.org/index.php/download/andro ...
- iOS常见面试题
一.为什么要在主线程中更新UI,这样做有什么好处? UIKit中的大部分类都不是“线程安全”的,为了解决这个线程不安全的问题,苹果推荐所有应用程序的UI操作都在主线程中执行,这样就不会出现多个线程同时 ...
- 全面分析 Spring 的编程式事务管理及声明式事务管理
开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...