一、什么是Ajax
Ajax(
Asynchronous JavaScript And XML
):指异步 JavaScript 及 XML。不是一种新的编程语言
,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术,是基于JavaScript、XML、HTML、CSS的新用法。
Ajax:只刷新局部页面的技术。包括以下几种技术:
- JavaScript:更新局部的网页。
- XML:一般用于请求数据和响应数据的封装。
XMLHttpRequest对象:发送请求到服务器并获得返回结果(浏览器内核创建的)。
- CSS:美化页面样式。
- 异步:发送请求后不等待返回结果,由回调函数处理结果。
JavaScript 中 XMLHttpRequest
对象是整个Ajax技术的核心,它提供了异步发送请求的能力。
构造方法:
不同浏览器,甚至相同浏览器的不同版本,获取该对象的方式是不同的。
var xmlhttp;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
复制代码
方法:
open() 该方法有3个参数,"get|post","url?name=tom","true
|false",默认为true。
send() 发送请求,可以带参数 或 null。
setRequestHeader() 设置请求消息头。
属性:
readyState 类型为short,只读
responseText 类型为String,只读
responseXML 类型为Document,只读(一般不用)
status 类型为short,只读
事件处理器:
onreadystatechange
二、常用方法
- open(method, URL, async) 建立与服务器的连接
method参数:指请求的HTTP方法,典型的值是GET或POST
URL参数:指请求的地址
async参数:指是否使用异步请求,其值为true
或false,默认值是true
,一般这个参数不写 - send(content) 发送请求
content参数:指请求的参数 - setRequestHeader(header, value) 设置请求的头信息
三、常用属性
onreadystatechange: 指定回调函数
readyState: XMLHttpRequest的状态信息(客户端:浏览器)
就绪状态码 说明 0 XMLHttpRequest对象没有完成初始化,即:刚刚创建。 1 XMLHttpRequest对象开始发送请求,即:调用了open方法,但还没有调用send方法。请求还没有发出。 2 XMLHttpRequest对象的请求发送完成,即:send方法已经调用,数据已经提交到服务器,但没有任何响应。 3 XMLHttpRequest对象开始读取响应,还没有结束,即:收到了所有的响应消息头,但正文还没有完全收到。 4 XMLHttpRequest对象读取响应结束,即: 一切都收到了
。status: HTTP的状态码(服务器端)
状态码 说明 200
服务器响应正常
400 无法找到请求的资源 403 没有访问权限 500 服务器内部错误 responseText: 获得响应的文本内容
responseXML: 获得响应的XML文档对象 documednt
注:客户端就绪状态码是4,且服务端状态码是200,才可以处理服务器数据。
示例代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/myJS.js">script>
<title>Insert title heretitle>
head>
<script type="text/javascript">
// 1、获取XMLHttpRequest对象
var req = getXMLHttpRequest();
// 4、处理响应结果
req.onreadystatechange = function() {
// alert(req.readyState); // 查看客户器端就绪状态码
if (req.readyState == 4) {
// alert(req.status); // 查看服务器端响应状态码
if (req.status == 200) { // 说明服务器响应一切正常
alert(req.responseText);
}
}
}
// 2、建立一个连接
req.open("get", "${ pageContext.request.contextPath }/servlet/servletDemo1");
// 3、发送请求
req.send(null);
script>
<body>
body>
html>
复制代码
使用Ajax验证用户名是否存在的实现步骤:
- 使用文本框的
onblur事件(失去焦点事件)
- 使用Ajax技术实现异步交互
a) 获取用户名
a) 创建 XMLHttpRequest 对象
b) 处理响应结果,创建回调函数,根据响应状态动态更新页面
c) 建立一个连接
d) 发送请求
示例代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/myJS.js">script>
<title>Insert title heretitle>
<script type="text/javascript">
function ckName() {
// 获取用户名对象
var name = document.getElementsByTagName("input")[0];
// 创建XMLHttpRequest对象
var xhr = getXMLHttpRequest();
// 处理响应结果,创建回调函数,根据响应状态动态更新页面
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { // 说明客户端请求一切正常
if (xhr.status == 200) { // 说明服务器响应一切正常
// alert(xhr.responseText); // 得到响应结果
var msg = document.getElementById("msg");
if (xhr.responseText == "true") {
// msg.innerText = "用户名已存在";
msg.innerHTML = "该用户名已存在";
} else {
msg.innerHTML = "该用户名可以使用";
}
}
}
}
// 建立一个连接
xhr.open("get", "${ pageContext.request.contextPath }/servlet/ckNameServlet?name=" + name.value + "&time=" + new Date().getTime());
// 发送请求
xhr.send(null);
}
script>
head>
<body>
用户名:<input type="text" name="userName" onblur="ckName()"/><span id="msg" >span>br>
密码:<input type="password" name="pwd" />br>
body>
html>
复制代码
验证用户名是否存在改进代码版本(该种方式,使得网页的标签很干净,感觉不到调用事件了):
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/myJS.js">script>
<title>Insert title heretitle>
<script type="text/javascript">
window.onload = function() {
var nameElement = document.getElementsByName("userName")[0];
nameElement.onblur = function() {
var name = this.value; // this等价于nameElement
// 创建XMLHttpRequest对象
var xhr = getXMLHttpRequest();
// 处理响应结果,创建回调函数,根据响应状态动态更新页面
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { // 说明客户端请求一切正常
if (xhr.status == 200) { // 说明服务器响应一切正常
// alert(xhr.responseText); // 得到响应结果
var msg = document.getElementById("msg");
if (xhr.responseText == "true") {
// msg.innerText = "用户名已存在";
msg.innerHTML = "该用户名已存在";
} else {
msg.innerHTML = "该用户名可以使用";
}
}
}
}
// 建立一个连接
xhr.open("get", "${pageContext.request.contextPath }/servlet/ckNameServlet?name=" + name + "&time=" + new Date().getTime());
// 发送请求
xhr.send(null);
}
}
script>
head>
<body>
用户名:<input type="text" name="userName" /><span id="msg" >span>br>
密码:<input type="password" name="pwd" />br>
body>
html>
复制代码
四、案例1:实现邮箱验证
- my.js
// 获取XMLHttpRequest对象
function getXMLHttpRequest() {
var xmlhttp;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
}
复制代码
- register.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/my.js">script>
<head>
<title>bookStore注册页面title>
<%--导入css --%>
<link rel="stylesheet" href="css/main.css" type="text/css" />
<script type="text/javascript">
function changeImage() {
document.getElementById("img").src = "${pageContext.request.contextPath}/imageCode?time="
+ new Date().getTime();
}
// 验证邮箱是否存在
function ckEmail() {
// 得到邮箱对象
var email = document.getElementByName("email")[0];
// 创建XMLHttpRequest对象
var xhr = getXMLHttpRequest();
// 处理响应结果,创建回调函数,根据响应状态动态更新页面
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.responseText); // 得到响应结果
// 得到邮箱的font标签
var font = document.getElementsByTagName("font")[0];
if (xhr.responseText == "true") {
font.innerHTML = "此邮箱已被使用";
font.style.color = "red";
} else {
font.innerHTML = "此邮箱可以使用";
font.style.color = "green";
}
}
}
}
// 建立一个连接
xhr.open("get", "${pageContext.request.contextPath}/servlet/ckEmailServlet?email=" + email.value + "&time=" + new Date().getTime());
// 发送请求
xhr.send(null);
}
script>
head>
<body class="main">
<%@include file="head.jsp"%>
<%--导入头 --%>
<%@include file="menu_search.jsp"%><%--导入导航条与搜索 --%>
<div id="divcontent">
<form action="${pageContext.request.contextPath}/register.jsp"
method="post">
<table width="850px" border="0" cellspacing="0">
<tr>
<td style="padding:30px">
<h1>新会员注册h1>
<table width="70%" border="0" cellspacing="2" class="upline">
<tr>
<td style="text-align:right; width:20%">会员邮箱:td>
<td style="width:40%">
<input type="text" class="textinput"
name="email" onblur="ckEmail()"/>td>
<td><font color="#999999">请输入有效的邮箱地址font>td>
tr>
.......
body>
html>
复制代码
- CkEmailServlet.java
package com.itheima.web.servlet;
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 CkEmailServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
String email = request.getParameter("email");
if ("[email protected]".equals(email)) {
out.print(true);
} else {
out.print(false);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
复制代码
五、案例2:搜索框显示数据
- 编写显示数据的容器div
- 实现ajax响应数据
// 创建XMLHttpRequest对象
// 通过事件调用回调函数处理响应结果
// 创建一个服务器连接
// 发送请求
示例代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<script type="text/javascript"
src="${pageContext.request.contextPath}/js/my.js">
script>
<script type="text/javascript">
window.onload = function() {
// 得到搜索框对象
var searchElement = document.getElementById("name");
// 得到父div元素对象
var div = document.getElementById("context1");
// 给文件框注册按键弹起事件
searchElement.onkeyup = function() {
// 先获取文本框的值
var name = this.value;
// 如果文本框没有数据时,就把父div隐藏,且不向服务器发送请求
if (name == "") {
div.style.display = "none";
return;
}
// 获得XMLHttpRequest对象
var xhr = getXMLHttpRequest();
// 处理结果
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { // 客户端请求一 切正常
if (xhr.status == 200) { // 服务器响应一切正常
var str = xhr.responseText; // 得到服务器返回的数据
var ss = str.split(","); // 把字符串 1001,1002,1003 切成数组
var childDivs = "";
// 循环把数据放入子div中
for (var i = 0; i < ss.length; i++) {
childDivs += ""
+ ss[i] + ""; // 把数组中的每个元素放到子div中
}
div.innerHTML = childDivs; // 把多个子div(childDivs)放入列表父div中
div.style.display = "block"; // 把列表隐藏
}
}
}
xhr.open("get", "${ pageContext.request.contextPath}/servlet/searchBookAJAXServlet?name=" + name + "&time=" + new Date().getTime());
xhr.send(null);
}
}
// 鼠标悬浮在子div时,改变背景色
function changeBackground_over(div) {
div.style.backgroundColor = "gray"; // backgroundColor js中属性的写法,background-color css中属性的写法
}
// 鼠标离开子div时,恢复背景色
function changeBackground_out(div) {
div.style.backgroundColor = "";
}
// 填充文本到搜索框
function writeText(div) {
// 先得到搜索框
var searchElement = document.getElementById("name");
// 把div中的文本添加到搜索框中
searchElement.value = div.innerHTML;
// 把父div(context1)隐藏
div.parentNode.style.display = "none";
}
script>
<div id="divmenu">
<a href="${pageContext.request.contextPath}/showProductByPage?category=文学">文学a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=生活">生活a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=计算机">计算机a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=外语">外语a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=经营">经管a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=励志">励志a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=社科">社科a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=学术">学术a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=少儿">少儿a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=艺术">艺术a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=原版">原版a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=科技">科技a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=考试">考试a>
<a href="${pageContext.request.contextPath}/showProductByPage?category=生活百科">生活百科a>
<a href="${pageContext.request.contextPath}/showProductByPage" style="color:#FFFF00">全部商品目录a>
div>
<div id="divsearch">
<form action="${pageContext.request.contextPath}/findProductBySearch"
method="post">
<table width="100%" border="0" cellspacing="0" >
<tr>
<td style="text-align:right; padding-right:220px">
Search
<input type="text" name="name" class="inputtable"
id="name" autocomplete="on"/>
<input type="image" src="images/serchbutton.gif"
border="0" style="margin-bottom:-4px">
td>
tr>
table>
form>
div>
<div id="context1" style="display:block; border:1px solid red; background-color:white;
width:128px; position:absolute; left:860px; top:135px;">
div>
复制代码
六、json对象的学习
示例代码如下:
json.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<script type="text/javascript">
/* json对象有些像java的普通类对象,java是纯面向对象,javascript是基于对象和事件的脚本语言。
// java语言创建的类
public class Person() {
private String name;
private int age;
public void show() {
}
}
*/
/*
// js语言创建的类,大小写均可,一般小写,为了更像一个类,这时我们大写
function Person() {
var name = "tom"; // 声明一个局部变量
this.age = 10; // 声明一个成员变量
this.show = function() {
alert(name);
}
}
var p = new Person();
document.write(p.name);
document.write(p.age);
p.show();
*/
var pp = [100, true, 12.34]; // 这是一个数组
var pp = { name:"tom", age:18,
show:function() {
alert("hello json");
}
}; // 这是一个json对象
document.write(pp.name);
document.write(pp.age);
pp.show();
var ppp = [ { name:"tom", age:18 }, { name:"lune", age:25 } ];
document.write(ppp[1].name)
script>
body>
html>
复制代码
JsonTest.java
package com.itheima.json;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;
import com.itheima.domain.Book;
import com.itheima.util.C3P0Util;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
public class JsonTest {
@Test // 使用 JSONObject对象封装对象数据
public void test1() {
Book b = new Book();
b.setId("10001");
b.setName("西游记");
b.setPnum(20);
String s = JSONObject.fromObject(b).toString();
System.out.println(s);
}
@Test // 使用 JSONArray对象封装 List对象数据
public void test2() throws SQLException {
List list = new ArrayList();
Book b1 = new Book();
b1.setId("10001");
b1.setName("西游记");
b1.setPnum(20);
Book b2 = new Book();
b2.setId("10002");
b2.setName("三国演义");
b2.setPnum(30);
Book b3 = new Book();
b3.setId("10003");
b3.setName("水浒传");
b3.setPnum(40);
list.add(b1);
list.add(b2);
list.add(b3);
String s = JSONArray.fromObject(list).toString();
System.out.println(s);
}
@Test // 使用 JSONArray对象封装 List对象数据 + 使用 JsonConfig对象过滤掉不想要的数据
public void test3() throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
List list = qr.query("select * from book", new BeanListHandler(Book.class));
JsonConfig jc = new JsonConfig();
jc.setExcludes(new String[]{"pnum", "description", "category", "id"});
String s = JSONArray.fromObject(list, jc).toString();
System.out.println(s);
}
}
复制代码