前言:这是我第一次接触Ajax这门技术,未免不感到陌生,故记录我的学习过程,以供未来人参考。其实虽然我之前是没有接触过这门技术,但还是可以看到这样的情况的,例如,在很多网站上实现注册功能的时候,需要输入用户名,当光标离开文本框的时候,会给我们这样一个提示:显示用户名已经存在或者用户名可以使用!那么这时就需要使用到Ajax这门技术了,现在让我们走进Ajax的大门,跟着我的步伐,前进吧!
Ajax的概述
什么是Ajax?
Ajax的英文全称是Asynchronous JavaScript And XML,即异步的JavaScript And XML,是指一种创建交互式网页应用的网页开发技术,它并不是一种新的技术,而是几种原有技术的结合体。它由下列技术组合而成。
- 使用CSS和XHTML来表示;
- 使用DOM模型来交互和动态显示;
- 使用XMLHttpRequest来和服务器进行异步通信;
- 使用JavaScript来绑定和调用。
在上面几中技术中,除了XMLHttpRequest对象以外,其它所有的技术都是基于web标准并且已经得到了广泛使用,XMLHttpRequest虽然目前还没有被W3C所采纳,但是它已经是一个事实的标准,因为目前几乎所有的主流浏览器都支持它。
虽然Ajax使用的是老的技术,但用的是新的思想。接下来,我们就应该了解一下同步和异步的区别。我们先来看同步,一图以蔽之。
当用户点击链接或者提交按钮,页面才会跳转,这时整个页面都会刷新。接着我们再来看异步:
当用户点击链接或者提交按钮,只会让页面的局部进行刷新。这样说来,那么Ajax的功能就是用来完成页面的局部刷新,而不中断用户的体验。此外,我也多说一嘴——早期的时候,JS技术根本不受重视,后台开发人员经常将JS当成一种玩具式语言,但JS中有一个非常重要的XMLHttpRequest对象,其可以向服务器异步发送请求。在传统的B/S结构的软件中,所有实现功能都需要在服务器端编写代码(称之为胖服务器,即服务器端特别臃肿)。现在有了Ajax以后,可以将部分代码写到客户端浏览器(RIA——Rich Internet Application,富浏览器端应用)中。
Ajax既然称之为异步的JavaScript And XML,那么XML代表什么呢?Ajax是使用XML做为数据传递的格式的,但实际上数据格式可以由JSON代替,进一步减少了数据量。
Ajax有什么用?
传统的网页,如果需要更新内容,必须加载整个网页。如果只需要对网页上的某个内容进行局部刷新,那么就需要使用到Ajax了。它可以让我们无需重新加载全部网页内容,即可完成对某个部分的内容执行刷新。最典型的的例子,莫过于大家在注册网站的时候,输入的用户名,会自动的提示我们该用户已被注册。
Ajax的内部原理
诚如我们前面所说的,Ajax并不是一项新技术。而是包装了现有的技术,然后使用它们来完成工作而已。那么现在给大家举个例子,还是以咱们的判断用户名是否已被注册为例。如若使用的是传统方式:
- 输入用户名;
- 点击一个按钮,校验;
- 把数据提交给服务器;
- 服务器在后台帮助我们完成校验,并且反馈信息;
- 我们在浏览器上提示用户,给出结果。
如若使用的是Ajax方式,那么Ajax方式与前面的方式其实从要做的事情来说,是一样的。Ajax也没有牛到,不用去访问服务器就知道你的用户名是否已被占用。那么它是如何工作的呢?
- 通过JS获取咱们的输入框文本内容,例如
document.getElementById("username").value
; - 通过XMLHttpRequest去执行请求。XMLHttpRequest其实就是XML+http+Request的组合;
- 请求结束后,收到结果,再使用JS去完成提示;
- 可以在顺便配合css样式来增加提示效果。
Ajax入门
XMLHttpRequest
我们学习Ajax,实际上就是学习XmlHttpRequest这个对象。下面我们将学习一下该对象的属性和方法。XMLHttpRequest对象的属性如下图所示:
对于以上属性,我还是稍微做一下解释:
-
readyState:XMLHttpRequest对象的状态。共有以下几种状态,如下图所示。
-
onreadystatechange:当XMLHttpRequest对象的状态改变时会触发的一个函数;
-
status:获得响应的状态码,例如200、404等等;
-
responseText:获得(异步加载后)响应的文本数据;
-
responseXML:获得(异步加载后)响应的XML数据;
XMLHttpRequest对象的方法如下图所示:
对于以上方法,我也稍微做一下解释:
- open(请求方式, 请求路径, 是否异步):异步去向服务器发送请求;
- send(请求参数):发送请求到http服务器并接收回应;
- setRequestHeader(头信息, 头的值):单独指定请求的某个http头,可用来处理POST请求方式的中文乱码问题;
如何创建XMLHttpRequest对象呢?
对于IE浏览器来说,它将XMLHttpRequest对象封装在一个ActiveXObject组件中;而对于Firefox、Opera 8.0+、Safari等浏览器来说,直接就可以创建XMLHttpRequest对象。这儿直接给出创建XMLHttpRequest对象的代码,如下所示:
function createXMLHttp(){
var xmlHttp;
try{ // Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e){
try{ // Internet Explorer
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); // 低级版本的IE
} catch (e){
try{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); // 较高级版本的IE
} catch (e) {
}
}
}
return xmlHttp;
}
Ajax编写的步骤
- 获得XmlHttpRequest对象;
- 设置XmlHttpRequest对象状态改变时来触发一个函数;
- 设置向后台提交的请求路径和请求方式;
- 发送请求。
Ajax入门案例
GET方式提交请求
首先创建一个动态web项目,例如AjaxProject,然后在该项目的WebContent目录下新建一个01_ajax_get目录,并在该目录下新建一个jsp页面——ajax_get.jsp,其内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>
<a href="" onclick="get()">使用Ajax方式发送GET请求</a>
</h3>
</body>
</html>
如果只想使用Ajax方式发送请求给服务器端,看服务器有没有收到这个请求,那么可以向下面这样做:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function ajaxFunction() {
var xmlHttp;
try { // Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {// Internet Explorer
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
return xmlHttp;
}
//执行get请求
function get() {
//1. 创建XMLHttpRequest对象
var request = ajaxFunction();
//2. 发送请求
/*
参数一:请求类型(GET or POST)
参数二:请求的路径,可用相对路径,例如DemoServlet01
参数三:是否异步,true or false
*/
request.open("GET", "/AjaxProject/DemoServlet01", true);
request.send();
}
</script>
</head>
<body>
<h3>
<a href="" onclick="get()">使用Ajax方式发送GET请求</a>
</h3>
</body>
</html>
此时,我们要编写服务器端响应请求的Servlet,于是在com.meimeixia.servlet包中编写一个DemoServlet01,其代码很简单,如下:
package com.meimeixia.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoServlet01 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("收到了一个请求...");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
启动tomcat服务器,然后在浏览器地址栏中输入http://localhost:8080/AjaxProject/01_ajax_get/ajax_get.jsp
进行访问,点击页面中的超链接,这样就能在Eclipse的控制台中看到以上Servlet要输出的内容了。
如果发送请求的同时,还想传送一些数据,那么ajax_get.jsp页面的内容就要修改为:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function ajaxFunction() {
var xmlHttp;
try { // Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {// Internet Explorer
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
return xmlHttp;
}
//执行get请求
function get() {
//1. 创建XMLHttpRequest对象
var request = ajaxFunction();
//2. 发送请求
/*
参数一:请求类型(GET or POST)
参数二:请求的路径,可用相对路径,例如DemoServlet01
参数三:是否异步,true or false
*/
//request.open("GET", "/AjaxProject/DemoServlet01", true);
request.open("GET", "/AjaxProject/DemoServlet01?name=liayun&age=18", true);
request.send();
}
</script>
</head>
<body>
<h3>
<a href="" onclick="get()">使用Ajax方式发送GET请求</a>
</h3>
</body>
</html>
此时,为了接收传送过来的数据,服务器端的DemoServlet01可以修改为:
package com.meimeixia.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoServlet01 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
String age = request.getParameter("age");
System.out.println("收到了一个请求..." + "name = " + name + ", age = " + age);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
重启tomcat服务器,然后在浏览器地址栏中输入http://localhost:8080/AjaxProject/01_ajax_get/ajax_get.jsp
进行访问,点击页面中的超链接,这样就能在Eclipse的控制台中看到以上Servlet要输出的内容了。
如果发送请求的同时,不仅想传送一些数据,而且还想获取服务器端回送给我们的数据,那么ajax_get.jsp页面的内容就要修改为:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function ajaxFunction() {
var xmlHttp;
try { // Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {// Internet Explorer
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
return xmlHttp;
}
//执行get请求
function get() {
//1. 创建XMLHttpRequest对象
var request = ajaxFunction();
//2. 发送请求
request.open("GET", "/AjaxProject/DemoServlet01?name=liayun&age=18", true);
//3. 获取响应数据,有点类似注册监听的意思,一会准备的状态发生了改变,那么就执行=号右边的方法
request.onreadystatechange = function() {
//前半段表示请求已经能够正常处理,再判断状态码是否是200
if (request.readyState == 4 && request.status == 200) {
//弹出响应的信息
alert(request.responseText);
}
}
request.send();
}
</script>
</head>
<body>
<h3>
<a href="" onclick="get()">使用Ajax方式发送GET请求</a>
</h3>
</body>
</html>
此时,为了接收传送过来的数据和回送一些数据,服务器端的DemoServlet01可以修改为:
package com.meimeixia.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoServlet01 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
String age = request.getParameter("age");
System.out.println("收到了一个请求..." + "name = " + name + ", age = " + age);
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("收到了请求...");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
重启tomcat服务器,然后在浏览器地址栏中输入http://localhost:8080/AjaxProject/01_ajax_get/ajax_get.jsp
进行访问,点击页面中的超链接,不仅弹出了响应的文本数据,而且在Eclipse的控制台中也可以看到以上Servlet要输出的内容。
POST方式提交请求
首先在AjaxProject项目的WebContent目录下新建一个02_ajax_post目录,并在该目录下新建一个jsp页面——ajax_post.jsp,其内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>
<a href="" onclick="post()">使用Ajax方式发送POST请求</a>
</h3>
</body>
</html>
如果发送请求的同时,还想传送一些数据,那么ajax_post.jsp页面的内容就要修改为:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function ajaxFunction() {
var xmlHttp;
try { // Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {// Internet Explorer
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
return xmlHttp;
}
function post() {
//1. 创建对象
var request = ajaxFunction();
//2. 发送请求
request.open("POST", "/AjaxProject/DemoServlet01", true);
//如果使用的是post方式带数据,那么这里要添加头,说明提交的数据类型是一个经过url编码的form表单数据
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//带数据过去,在send方法里面写表单数据
request.send("name=aobama&age=19");
}
</script>
</head>
<body>
<h3>
<a href="" onclick="post()">使用Ajax方式发送POST请求</a>
</h3>
</body>
</html>
此时,为了接收传送过来的数据,服务器端的DemoServlet01可以修改为:
package com.meimeixia.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoServlet01 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
String age = request.getParameter("age");
System.out.println("收到了一个请求..." + "name = " + name + ", age = " + age);
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("收到了请求...");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("现在来了一个post请求,将要去走doGet方法里面的代码了");
doGet(request, response);
}
}
重启tomcat服务器,然后在浏览器地址栏中输入http://localhost:8080/AjaxProject/02_ajax_post/ajax_post.jsp
进行访问,点击页面中的超链接,这样就能在Eclipse的控制台中看到以上Servlet要输出的内容了。
如果发送请求的同时,不仅想传送一些数据,而且还想获取服务器端回送给我们的数据,那么ajax_post.jsp页面的内容就要修改为:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function ajaxFunction() {
var xmlHttp;
try { // Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {// Internet Explorer
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
return xmlHttp;
}
function post() {
//1. 创建对象
var request = ajaxFunction();
//2. 发送请求
request.open("POST", "/AjaxProject/DemoServlet01", true);
//想获取服务器传送过来的数据,加一个状态的监听
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
alert("post:" + request.responseText);
}
}
//如果使用的是post方式带数据,那么这里要添加头,说明提交的数据类型是一个经过url编码的form表单数据
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//带数据过去,在send方法里面写表单数据
request.send("name=aobama&age=19");
}
</script>
</head>
<body>
<h3>
<a href="" onclick="post()">使用Ajax方式发送POST请求</a>
</h3>
</body>
</html>
重启tomcat服务器,然后在浏览器地址栏中输入http://localhost:8080/AjaxProject/02_ajax_post/ajax_post.jsp
进行访问,点击页面中的超链接,不仅弹出了响应的文本数据,而且在Eclipse的控制台中也可以看到以上Servlet要输出的内容。