ajax 学习

同步交互与异步交互

  1. 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
  2. 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

2. 异步交互和同步交互
  * 同步:
    > 发一个请求,就要等待服务器的响应结束,然后才能发第二个请求!中间这段时间就是一个字“卡”
    > 刷新的是整个页面!
  * 异步:
    > 发一个请求后,无需等待服务器的响应,然后就可以发第二个请求!
    > 可以使用js接收服务器的响应,然后使用js来局部刷新!

 

js的局部刷新介绍

<script type="text/javascript">
window.onload = function() {//在文档加载完成后马上执行!
	//得到btn元素
	var btn = document.getElementById("btn");
	// 给btn的click事件注册监听
	btn.onclick = function() {//在按按钮被点击时执行!
		// 获取h1元素对应的DOM对象
		var h1 = document.getElementById("h1");
		// 给h1添加内容
		h1.innerHTML = "Hello JS!!!";
	};
};
</script>
  </head>
  
  <body>
<button id="btn">点击这里</button>
<h1 id="h1"></h1>
  </body>
</html>

这就是js 的局部刷新

ajax = js内置局部刷新+ 服务器的响应

asynchronous javascript and xml:异步的js和xml(服务器返回的数据)

js 没有办法发送请求,但是通过ajax 技术可以 发送一个异步请求,正常情况下,

服务器给客户端的响应一般是整个页面,一个html完整页面!但在ajax中因为是局部刷新,那么服务器就不用再响应整个页面!而只是数据(就不再是html里面的标签,就只是标签里面的内容)


 那么怎么把java 的对象发给js 呢,这里面就涉及到两种语言的交互方式,只有字符串两种语言都可以识别,下面的三种文件格式两种语言,服务器和客户端都可以识别,用来装字符串。

  > text:太不好写了,没有任何格式要求
    > xml:可以表示多个对象,因为曾经用xml 做过数据库,所以就是可以的
    > json:它是js提供的数据交互格式,它在ajax中最受欢迎!

 

AJAX常见应用情景

不用等待下拉框,就可以点击百度

当我们在百度中输入一个“传”字后,会马上出现一个下拉列表!列表中显示的是包含“传”字的10个关键字。

其实这里就使用了AJAX技术!当文件框发生了输入变化时,浏览器会使用AJAX技术向服务器发送一个请求,查询包含“传”字的前10个关键字,然后服务器会把查询到的结果响应给浏览器,最后浏览器把这10个关键字显示在下拉列表中。

  1. 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
  2. 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

 

 

当输入用户名后,把光标移动到其他表单项上时,引发失去光标事件,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为zhangSan的用户是否存在,最终服务器返回true表示名为zhangSan的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。

  1. 整个过程中页面没有刷新,只是局部刷新了;
  2. 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;

好处就是提高了用户的体验度,不用等待响应就可以点击请求

 

4. ajax的优缺点
  优点:
  * 异步交互:增强了用户的体验!
  * 性能:因为服务器无需再响应整个页面,只需要响应部份内容,所以服务器的压力减轻了!

  缺点:
  * ajax不能应用在所有场景!
  * ajax无端的增多了对服务器的访问次数,给服务器带来了压力!

ajax发送异步请求(四步操作)

1. 第一步(得到XMLHttpRequest)
  * ajax其实只需要学习一个对象:XMLHttpRequest,如果掌握了它,就掌握了ajax!!!
  * 得到XMLHttpRequest
    > 大多数浏览器都支持:var xmlHttp = new XMLHttpRequest();
    > IE6.0:var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    > IE5.5以更早版本的IE:var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

  * 编写创建XMLHttpRequest对象的函数
  function createXMLHttpRequest() {
      try {
          return new XMLHttpRequest();
      } catch(e) {
          try {
          return new ActiveXObject("Msxml2.XMLHTTP");
      } catch(e) {
          try {
              return new ActiveXObject("Microsoft.XMLHTTP");
          } catch(e) {
              alert("哥们儿,你用的是什么浏览器啊?");
              throw e;
          }
      }
      }
  }

2. 第二步(打开与服务器的连接)
  * xmlHttp.open():用来打开与服务器的连接,它需要三个参数:
    > 请求方式:可以是GET或POST
    > 请求的URL:指定服务器端资源,例如;/day23_1/AServlet
    > 请求是否为异步:如果为true表示发送异步请求,否则同步请求!
  * xmlHttp.open("GET", "/day23_1/AServlet", true);

3. 第三步(发送请求)
  * xmlHttp.send(null):如果不给可能会造成部份浏览器无法发送!
    > 参数:就是请求体内容!如果是GET请求,必须给出null,由于get请求没有请求体。

4. 第四步()
  * 在xmlHttp对象的一个事件上注册监听器:onreadystatechange
  * xmlHttp对象一共有5个状态:
    > 0状态:刚创建,还没有调用open()方法;
    > 1状态:请求开始:调用了open()方法,但还没有调用send()方法
    > 2状态:调用完了send()方法了;
    > 3状态:服务器已经开始响应,但不表示响应结束了!
    > 4状态:服务器响应结束!(通常我们只关心这个状态!!!)
  * 得到xmlHttp对象的状态:
    > var state = xmlHttp.readyState;//可能是0、1、2、3、4
  * 得到服务器响应的状态码
    > var status = xmlHttp.status;//例如为200、404、500
  * 得到服务器响应的内容1
    > var content = xmlHttp.responseText;//得到服务器的响应的文本格式的内容
    > var content = xmlHttp.responseXML;//得到服务器的响应的xml响应的内容,它是Document对象了!

  xmlHttp.onreadystatechange = function() {//xmlHttp的5种状态都会调用本方法
      if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {//双重判断:判断是否为4状态,而且还要判断是否为200
          // 获取服务器的响应内容
      var text = xmlHttp.responseText;
      }
  };

案例1 get 请求

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'ajax1.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
<script type="text/javascript">
// 创建异步对象
function createXMLHttpRequest() {
	try {
		return new XMLHttpRequest();//大多数浏览器
	} catch (e) {
		try {
			return ActvieXObject("Msxml2.XMLHTTP");//IE6.0
		} catch (e) {
			try {
				return ActvieXObject("Microsoft.XMLHTTP");//IE5.5及更早版本	
			} catch (e) {
				alert("哥们儿,您用的是什么浏览器啊?");
				throw e;
			}
		}
	}
}

window.onload = function() {//文档加载完毕后执行
	var btn = document.getElementById("btn");
	btn.onclick = function() {//给按钮的点击事件注册监听
		/*
		ajax四步操作,得到服务器的响应
		把响应结果显示到h1元素中
		*/
		/*
		1. 得到异步对象 
		*/
		var xmlHttp = createXMLHttpRequest();
		/*
		2. 打开与服务器的连接
		  * 指定请求方式
		  * 指定请求的URL
		  * 指定是否为异步请求
		*/
		//由于从服务器响应回来的是一个html ,由于是从服务器过来的所以路径/AServlet 实际神是day23_1/AServlet
		xmlHttp.open("GET", "<c:url value='/AServlet'/>", true);
		/*
		3. 发送请求
		*/
		xmlHttp.send(null);//GET请求没有请求体,但也要给出null,不然FireFox可能会不能发送!
		/*
		4. 给异步对象的onreadystatechange事件注册监听器
		*/
		xmlHttp.onreadystatechange = function() {//当xmlHttp的状态发生变化时执行
			// 双重判断:xmlHttp的状态为4(服务器响应结束),以及服务器响应的状态码为200(响应成功)
			if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
				// 获取服务器的响应结束
				var text = xmlHttp.responseText;
				// 获取h1元素
				var h1 = document.getElementById("h1");
				h1.innerHTML = text;
			}
		};
	};
};
</script>
  </head>
  
  <body>
<button id="btn">点击这里</button>
<h1 id="h1"></h1>
  </body>
</html>

 

第二例:发送POST请求(如果发送请求时需要带有参数,一般都用POST请求)

* open:xmlHttp.open("POST" ....);
* 添加一步:设置Content-Type请求头:
  > xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
* send:xmlHttp.send("username=zhangSan&password=123");//发送请求时指定请求体

package cn.itcast.web.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 AServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("Hello AJAX!");
		response.getWriter().print("Hello AJAX!!!");
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("UTF-8");
		
		String username = request.getParameter("username");//获取请求参数
		System.out.println("(POST:) Hello AJAX!" + username);
		response.getWriter().print("(POST:) Hello AJAX!!!" + username);
	}
}
package cn.itcast.web.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 AServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("Hello AJAX!");
		response.getWriter().print("Hello AJAX!!!");
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("UTF-8");
		
		String username = request.getParameter("username");//获取请求参数
		System.out.println("(POST:) Hello AJAX!" + username);
		response.getWriter().print("(POST:) Hello AJAX!!!" + username);
	}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'ajax1.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
<script type="text/javascript">
// 创建异步对象
function createXMLHttpRequest() {
	try {
		return new XMLHttpRequest();//大多数浏览器
	} catch (e) {
		try {
			return ActvieXObject("Msxml2.XMLHTTP");//IE6.0
		} catch (e) {
			try {
				return ActvieXObject("Microsoft.XMLHTTP");//IE5.5及更早版本	
			} catch (e) {
				alert("哥们儿,您用的是什么浏览器啊?");
				throw e;
			}
		}
	}
}

window.onload = function() {//文档加载完毕后执行
	var btn = document.getElementById("btn");
	btn.onclick = function() {//给按钮的点击事件注册监听
		/*
		ajax四步操作,得到服务器的响应
		把响应结果显示到h1元素中
		*/
		/*
		1. 得到异步对象 
		*/
		var xmlHttp = createXMLHttpRequest();
		/*
		2. 打开与服务器的连接
		  * 指定请求方式
		  * 指定请求的URL
		  * 指定是否为异步请求
		*/
		/************修改open方法,指定请求方式为POST**************/
		xmlHttp.open("POSt", "<c:url value='/AServlet'/>", true);
		/************设置请求头:Content-Type************/
		xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		/*
		3. 发送请求
		*/
		/**********发送时指定请求体***********/
		xmlHttp.send("username=张三&password=123");//GET请求没有请求体,但也要给出null,不然FireFox可能会不能发送!
		/*
		4. 给异步对象的onreadystatechange事件注册监听器
		*/
		xmlHttp.onreadystatechange = function() {//当xmlHttp的状态发生变化时执行
			// 双重判断:xmlHttp的状态为4(服务器响应结束),以及服务器响应的状态码为200(响应成功)
			if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
				// 获取服务器的响应结束
				var text = xmlHttp.responseText;
				// 获取h1元素
				var h1 = document.getElementById("h1");
				h1.innerHTML = text;
			}
		};
	};
};
</script>
  </head>
  
  <body>
<button id="btn">点击这里</button>
<h1 id="h1"></h1>
  </body>
</html>

 

第三例:注册表单之校验用户是否注册!

1. 编写页面:
  * ajax3.jsp
    > 给出注册表单页面
    > 给用户名文本框添加onblur事件的监听
    > 获取文本框的内容,通过ajax4步发送给服务器,得到响应结果
      * 如果为1:在文本框后显示“用户名已被注册”
      * 如果为0:什么都不做!

2. 编写Servlet
  * ValidateUsernameServlet
    > 获取客户端传递的用户名参数
    > 判断是否为itcast
      * 是:返回1
      * 否:返回0

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'ajax3.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
<script type="text/javascript">
//创建异步对象
function createXMLHttpRequest() {
	try {
		return new XMLHttpRequest();//大多数浏览器
	} catch (e) {
		try {
			return ActvieXObject("Msxml2.XMLHTTP");//IE6.0
		} catch (e) {
			try {
				return ActvieXObject("Microsoft.XMLHTTP");//IE5.5及更早版本	
			} catch (e) {
				alert("哥们儿,您用的是什么浏览器啊?");
				throw e;
			}
		}
	}
}


window.onload = function() {
	// 获取文本框,给它的失去焦点事件注册监听
	var userEle = document.getElementById("usernameEle");
	userEle.onblur = function() {
		//1.得到异步对象
		var xmlHttp = createXMLHttpRequest();
		//2.打开连接
		xmlHttp.open("POST", "<c:url value='/ValidateUsernameServlet'/>", true);
		//3.设置请求头:Content-Type
		xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		//4.发送请求,给出请求体
		xmlHttp.send("username=" + userEle.value);
		
		//5.给xmlHttp的onreadystatechange事件注册监听
		xmlHttp.onreadystatechange = function() {
			if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {//双重判断
				//获取服务器的响应,判断是否为1
				// 是:获取span,添加内容:“用户名已被注册”
				var text = xmlHttp.responseText;
				var span = document.getElementById("errorSpan");
				if(text == "1") {
					//得到span元素
					span.innerHTML = "用户名已被注册!";
				} else {
					span.innerHTML = "";
				}
			}
		};
	};
};
</script>
  </head>
  
  <body>
<h1>演示用户名是否被注册</h1>
<form action="" method="post">
用户名:<input type="text" name="username" id="usernameEle"/><span id="errorSpan"></span><br/>
密 码:<input type="password" name="password"/><br/>
<input type="submit" value="注册"/>
</form>
  </body>
</html>
package cn.itcast.web.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 ValidateUsernameServlet extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		/*
		 * 1. 获取参数username
		 * 2. 判断是否为itcast
		 *   3. 如果是:响应1
		 *   4. 如果不是:响应0
		 */
		String username = request.getParameter("username");
		if(username.equalsIgnoreCase("itcast")) {
			response.getWriter().print("1");
		} else {
			response.getWriter().print("0");
		}
	}

}

 

响应内容为xml数据

  * 服务器端:
    > 设置响应头:ContentType,其值为:text/xml;charset=utf-8
  * 客户端:
    > var doc = xmlHttp.responseXML;//得到的是Document对象!

第四例:响应内容为xml数据

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'ajax1.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
<script type="text/javascript">
// 创建异步对象
function createXMLHttpRequest() {
	try {
		return new XMLHttpRequest();//大多数浏览器
	} catch (e) {
		try {
			return ActvieXObject("Msxml2.XMLHTTP");//IE6.0
		} catch (e) {
			try {
				return ActvieXObject("Microsoft.XMLHTTP");//IE5.5及更早版本	
			} catch (e) {
				alert("哥们儿,您用的是什么浏览器啊?");
				throw e;
			}
		}
	}
}

window.onload = function() {//文档加载完毕后执行
	var btn = document.getElementById("btn");
	btn.onclick = function() {//给按钮的点击事件注册监听
		/*
		ajax四步操作,得到服务器的响应
		把响应结果显示到h1元素中
		*/
		/*
		1. 得到异步对象 
		*/
		var xmlHttp = createXMLHttpRequest();
		/*
		2. 打开与服务器的连接
		  * 指定请求方式
		  * 指定请求的URL
		  * 指定是否为异步请求
		*/
		xmlHttp.open("GET", "<c:url value='/BServlet'/>", true);
		/*
		3. 发送请求
		*/
		xmlHttp.send(null);//GET请求没有请求体,但也要给出null,不然FireFox可能会不能发送!
		/*
		4. 给异步对象的onreadystatechange事件注册监听器
		*/
		xmlHttp.onreadystatechange = function() {//当xmlHttp的状态发生变化时执行
			// 双重判断:xmlHttp的状态为4(服务器响应结束),以及服务器响应的状态码为200(响应成功)
			if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
				// 获取服务器的响应结果(xml)
				var doc = xmlHttp.responseXML;
				// 查询文档下名为student的所有元素,得到数组,再取下标0元素
				var ele = doc.getElementsByTagName("student")[0];
				var number = ele.getAttribute("number");//获取元素名为number的属性值
				var name;
				var age;
				var sex;
				
				// 处理浏览器的差异
				if(window.addEventListener) {
					name = ele.getElementsByTagName("name")[0].textContent;//其他浏览器
				} else {
					name = ele.getElementsByTagName("name")[0].text;//IE支持
				}
				if(window.addEventListener) {
					age = ele.getElementsByTagName("age")[0].textContent;//其他浏览器
				} else {
					age = ele.getElementsByTagName("age")[0].text;//IE支持
				}
				if(window.addEventListener) {
					sex = ele.getElementsByTagName("sex")[0].textContent;//其他浏览器
				} else {
					sex = ele.getElementsByTagName("sex")[0].text;//IE支持
				}

				var text = number + ", " + name + ", " + age + ", " + sex;
				document.getElementById("h1").innerHTML = text;
			}
		};
	};
};
</script>
  </head>
  
  <body>
<button id="btn">点击这里</button>
<h1 id="h1"></h1>
  </body>
</html>
package cn.itcast.web.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 BServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String xml = "<students>" +
			"<student number='ITCAST_1001'>" +
			"<name>zhangSan</name>" +
			"<age>18</age>" + 
			"<sex>male</sex>" +
			"</student>" +
			"</students>";
		
		response.setContentType("text/xml;charset=utf-8");
		response.getWriter().print(xml);
	}
}

 

 

 

第五例:省市联动

1. 页面
  <select name="province">
    <option>===请选择省份===</option>
  </select>
  <select name="city">
    <option>===请选择城市===</option>  
  </select>

2. ProvinceServlet
  * ProvinceServlet:当页面加载完毕后马上请求这个Servlet!
    > 它需要加载china.xml文件,把所有的省的名称使用字符串发送给客户端!

3. 页面的工作
  * 获取这个字符串,使用逗号分隔,得到数组
  * 循环遍历每个字符串(省份的名称),使用每个字符串创建一个<option>元素添加到<select name="province">这个元素中

4. CityServlet
  * CityServlet:当页面选择某个省时,发送请求!
  * 得到省份的名称,加载china.xml文件,查询出该省份对应的元素对象!,把这个元素转换成xml字符串,发送给客户端

5. 页面的工作
  * 把<select name="city">中的所有子元素删除,但不要删除<option>===请选择城市===</option>
  * 得到服务器的响应结果:doc!!!
  * 获取所有的<city>子元素,循环遍历,得到<city>的内容
  * 使用每个<city>的内容创建一个<option>元素,添加到<select name="city">

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'ajax5.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
<script type="text/javascript">
function createXMLHttpRequest() {
	try {
		return new XMLHttpRequest();//大多数浏览器
	} catch (e) {
		try {
			return ActvieXObject("Msxml2.XMLHTTP");//IE6.0
		} catch (e) {
			try {
				return ActvieXObject("Microsoft.XMLHTTP");//IE5.5及更早版本	
			} catch (e) {
				alert("哥们儿,您用的是什么浏览器啊?");
				throw e;
			}
		}
	}
}
/*
 * 1. 在文档加载完毕时发送请求,得到所有省份名称,显示在<select name="province"/>中
 * 2. 在选择了新的省份时,发送请求(参数为省名称),得到xml文档,即<province>元素
 *   解析xml文档,得到其中所有的<city>,再得到每个<city>元素的内容,即市名,使用市名生成<option>,插入到<select name="city">元素中
 */

window.onload = function() {
	/*
	ajax四步,请求ProvinceServlet,得到所有省份名称
	使用每个省份名称创建一个<option>元素,添加到<select name="province">中
	*/
	var xmlHttp = createXMLHttpRequest();
	xmlHttp.open("GET", "<c:url value='/ProvinceServlet'/>", true);
	xmlHttp.send(null);
	xmlHttp.onreadystatechange = function() {
		if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
			// 获取服务器的响应
			var text = xmlHttp.responseText;
			// 使用逗号分隔它,得到数组
			var arr = text.split(",");
			// 循环遍历每个省份名称,每个名称生成一个option对象,添加到<select>中
			for(var i = 0; i < arr.length; i++) {
				var op = document.createElement("option");//创建一个指名名称元素
				op.value = arr[i];//设置op的实际值为当前的省份名称
				var textNode = document.createTextNode(arr[i]);//创建文本节点
				op.appendChild(textNode);//把文本子节点添加到op元素中,指定其显示值
				
				document.getElementById("p").appendChild(op);
			}
		}
	};
	
	
	/*
	第二件事情:给<select name="province">添加改变监听
	使用选择的省份名称请求CityServlet,得到<province>元素(xml元素)!!!
	获取<province>元素中所有的<city>元素,遍历之!获取每个<city>的文本内容,即市名称
	使用每个市名称创建<option>元素添加到<select name="city">
	*/
	var proSelect = document.getElementById("p");
	proSelect.onchange = function() {
		var xmlHttp = createXMLHttpRequest();
		xmlHttp.open("POST", "<c:url value='/CityServlet'/>", true);
		xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		xmlHttp.send("pname=" + proSelect.value);//把下拉列表中选择的值发送给服务器!
		xmlHttp.onreadystatechange = function() {
			if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
				/*
				把select中的所有option移除(除了请选择)
				*/
				var citySelect = document.getElementById("c");
				// 获取其所有子元素
				var optionEleList = citySelect.getElementsByTagName("option");
				// 循环遍历每个option元素,然后在citySelect中移除
				while(optionEleList.length > 1) {//子元素的个数如果大于1就循环,等于1就不循环了!
					citySelect.removeChild(optionEleList[1]);//总是删除1下标,因为1删除了,2就变成1了!
				}
				
				
				var doc = xmlHttp.responseXML;
				// 得到所有名为city的元素
				var cityEleList = doc.getElementsByTagName("city");
				// 循环遍历每个city元素
				for(var i = 0; i < cityEleList.length; i++) {
					var cityEle = cityEleList[i];//得到每个city元素
					var cityName;
					// 获取市名称
					if(window.addEventListener) {//处理浏览器的差异
						cityName = cityEle.textContent;//支持FireFox等浏览器
					} else {
						cityName = cityEle.text;//支持IE
					}
					
					// 使用市名称创建option元素,添加到<select name="city">中
					var op = document.createElement("option");
					op.value = cityName;
					// 创建文本节点
					var textNode = document.createTextNode(cityName);
					op.appendChild(textNode);//把文本节点追加到op元素中
					
					//把op添加到<select>元素中
					citySelect.appendChild(op);
				}
			}
		};		
	};
};
</script>
  </head>
  
  <body>
<h1>省市联动</h1>
<select name="province" id="p">
  <option>===请选择省===</option>
</select>
   
<select name="city" id="c">
  <option>===请选择市===</option>
</select>
  </body>
</html>
package cn.itcast.web.servlet;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class CityServlet extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/xml;charset=utf-8");//注意:发送xml这里要修改!!!
		
		/*
		 * 获取省份名称,加载该省对应的<province>元素!
		 * 把元素转换成字符串发送给客户端
		 */
		/*
		 * 1. 获取省份的名称
		 * 2. 使用省份名称查找到对应的<province>元素
		 * 3. 把<province>元素转换成字符串,发送!
		 */
		try {
			/*
			 * 得到Document
			 */
			SAXReader reader = new SAXReader();
			InputStream input = this.getClass().getResourceAsStream("/china.xml");
			Document doc = reader.read(input);
			
			/*
			 * 获取参数
			 */
			String pname = request.getParameter("pname");//获取省份名称
			Element proEle = (Element) doc.selectSingleNode("//province[@name='" + pname + "']");
			String xmlStr = proEle.asXML();//把元素转换成字符串
			response.getWriter().print(xmlStr);
		} catch(Exception e) {
			throw new RuntimeException(e);
		}
	}
}
package cn.itcast.web.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;

public class ProvinceServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		/*
		 * 响应所有省份名称,使用逗号分隔!
		 */
		/*
		 * 1. Document对象
		 *   * 创建解析器对象
		 *   * 调用解析器的读方法,传递一个流对象,得到Document
		 */
		try {
			SAXReader reader = new SAXReader();
			InputStream input = this.getClass().getResourceAsStream("/china.xml");
			Document doc = reader.read(input);
			
			/*
			 * 查询所有province的name属性,得到一堆的属性对象
			 * 循环遍历,把所有的属性值连接成一个字符串,发送给客户端
			 */
			List<Attribute> arrList = doc.selectNodes("//province/@name");
			StringBuilder sb = new StringBuilder();
			for(int i = 0; i < arrList.size(); i++) {
				sb.append(arrList.get(i).getValue());//把每个属性的值存放到sb中。
				if(i < arrList.size() - 1) {
					sb.append(",");
				}
			}
			response.getWriter().print(sb);
		} catch(Exception e) {
			throw new RuntimeException(e);
		}
	}
}

<?xml version="1.0" encoding="utf-8"?>
<china>
	<province name="北京">
		<city>东城区</city>
		<city>西城区</city>
		<city>崇文区</city>
		<city>宣武区</city>
		<city>朝阳区</city>
		<city>丰台区</city>
		<city>石景山区</city>
		<city>海淀区</city>
		<city>门头沟区</city>
		<city>房山区</city>
		<city>通州区</city>
		<city>顺义区</city>
		<city>昌平区</city>
		<city>大兴区</city>
		<city>怀柔区</city>
		<city>平谷区</city>
		<city>密云县</city>
		<city>延庆县</city>
	</province>
	<province name="天津">
		<city>和平区</city>
		<city>河东区</city>
		<city>河西区</city>
		<city>南开区</city>
		<city>河北区</city>
		<city>红桥区</city>
		<city>塘沽区</city>
		<city>汉沽区</city>
		<city>大港区</city>
		<city>东丽区</city>
		<city>西青区</city>
		<city>津南区</city>
		<city>北辰区</city>
		<city>武清区</city>
		<city>宝坻区</city>
		<city>宁河县</city>
		<city>静海县</city>
		<city>蓟县</city>
	</province>
	<province name="河北">
		<city>石家庄</city>
		<city>唐山</city>
		<city>秦皇岛</city>
		<city>邯郸</city>
		<city>邢台</city>
		<city>保定</city>
		<city>张家口</city>
		<city>承德</city>
		<city>沧州</city>
		<city>廊坊</city>
		<city>衡水</city>
	</province>
	<province name="山西">
		<city>太原</city>
		<city>大同</city>
		<city>阳泉</city>
		<city>长治</city>
		<city>晋城</city>
		<city>朔州</city>
		<city>晋中</city>
		<city>运城</city>
		<city>忻州</city>
		<city>临汾</city>
		<city>吕梁</city>
	</province>
	<province name="内蒙古">
		<city>呼和浩特</city>
		<city>包头</city>
		<city>乌海</city>
		<city>赤峰</city>
		<city>通辽</city>
		<city>鄂尔多斯</city>
		<city>呼伦贝尔</city>
		<city>巴彦淖尔</city>
		<city>乌兰察布</city>
		<city>兴安盟</city>
		<city>锡林郭勒盟</city>
		<city>阿拉善盟</city>
	</province>
	<province name="辽宁">
		<city>沈阳</city>
		<city>大连</city>
		<city>鞍山</city>
		<city>抚顺</city>
		<city>本溪</city>
		<city>丹东</city>
		<city>锦州</city>
		<city>营口</city>
		<city>阜新</city>
		<city>辽阳</city>
		<city>盘锦</city>
		<city>铁岭</city>
		<city>朝阳</city>
		<city>葫芦岛</city>
	</province>
	<province name="吉林">
		<city>长春</city>
		<city>吉林</city>
		<city>四平</city>
		<city>辽源</city>
		<city>通化</city>
		<city>白山</city>
		<city>松原</city>
		<city>白城</city>
		<city>延边</city>
	</province>
	<province name="黑龙江">
		<city>哈尔滨</city>
		<city>齐齐哈尔</city>
		<city>鸡西</city>
		<city>鹤岗</city>
		<city>双鸭山</city>
		<city>大庆</city>
		<city>伊春</city>
		<city>佳木斯</city>
		<city>七台河</city>
		<city>牡丹江</city>
		<city>黑河</city>
		<city>绥化</city>
		<city>大兴安岭</city>
	</province>
	<province name="上海">
		<city>黄浦区</city>
		<city>卢湾区</city>
		<city>徐汇区</city>
		<city>长宁区</city>
		<city>静安区</city>
		<city>普陀区</city>
		<city>闸北区</city>
		<city>虹口区</city>
		<city>杨浦区</city>
		<city>闵行区</city>
		<city>宝山区</city>
		<city>嘉定区</city>
		<city>浦东新区</city>
		<city>金山区</city>
		<city>松江区</city>
		<city>青浦区</city>
		<city>南汇区</city>
		<city>奉贤区</city>
		<city>崇明县</city>
	</province>
	<province name="江苏">
		<city>南京</city>
		<city>无锡</city>
		<city>徐州</city>
		<city>常州</city>
		<city>苏州</city>
		<city>南通</city>
		<city>连云港</city>
		<city>淮安</city>
		<city>盐城</city>
		<city>扬州</city>
		<city>镇江</city>
		<city>泰州</city>
		<city>宿迁</city>
	</province>
	<province name="浙江">
		<city>杭州</city>
		<city>宁波</city>
		<city>温州</city>
		<city>嘉兴</city>
		<city>湖州</city>
		<city>绍兴</city>
		<city>金华</city>
		<city>衢州</city>
		<city>舟山</city>
		<city>台州</city>
		<city>丽水</city>
	</province>
	<province name="安徽">
		<city>合肥</city>
		<city>芜湖</city>
		<city>蚌埠</city>
		<city>淮南</city>
		<city>马鞍山</city>
		<city>淮北</city>
		<city>铜陵</city>
		<city>安庆</city>
		<city>黄山</city>
		<city>滁州</city>
		<city>阜阳</city>
		<city>宿州</city>
		<city>巢湖</city>
		<city>六安</city>
		<city>亳州</city>
		<city>池州</city>
		<city>宣城</city>
	</province>
	<province name="福建">
		<city>福州</city>
		<city>厦门</city>
		<city>莆田</city>
		<city>三明</city>
		<city>泉州</city>
		<city>漳州</city>
		<city>南平</city>
		<city>龙岩</city>
		<city>宁德</city>
	</province>
	<province name="江西">
		<city>南昌</city>
		<city>景德镇</city>
		<city>萍乡</city>
		<city>九江</city>
		<city>新余</city>
		<city>鹰潭</city>
		<city>赣州</city>
		<city>吉安</city>
		<city>宜春</city>
		<city>抚州</city>
		<city>上饶</city>
	</province>
	<province name="山东">
		<city>济南</city>
		<city>青岛</city>
		<city>淄博</city>
		<city>枣庄</city>
		<city>东营</city>
		<city>烟台</city>
		<city>潍坊</city>
		<city>济宁</city>
		<city>泰安</city>
		<city>威海</city>
		<city>日照</city>
		<city>莱芜</city>
		<city>临沂</city>
		<city>德州</city>
		<city>聊城</city>
		<city>滨州</city>
		<city>荷泽</city>
	</province>
	<province name="河南">
		<city>郑州</city>
		<city>开封</city>
		<city>洛阳</city>
		<city>平顶山</city>
		<city>安阳</city>
		<city>鹤壁</city>
		<city>新乡</city>
		<city>焦作</city>
		<city>濮阳</city>
		<city>许昌</city>
		<city>漯河</city>
		<city>三门峡</city>
		<city>南阳</city>
		<city>商丘</city>
		<city>信阳</city>
		<city>周口</city>
		<city>驻马店</city>
	</province>
	<province name="湖北">
		<city>武汉</city>
		<city>黄石</city>
		<city>十堰</city>
		<city>宜昌</city>
		<city>襄樊</city>
		<city>鄂州</city>
		<city>荆门</city>
		<city>孝感</city>
		<city>荆州</city>
		<city>黄冈</city>
		<city>咸宁</city>
		<city>随州</city>
		<city>恩施</city>
		<city>神农架</city>
	</province>
	<province name="湖南">
		<city>长沙</city>
		<city>株洲</city>
		<city>湘潭</city>
		<city>衡阳</city>
		<city>邵阳</city>
		<city>岳阳</city>
		<city>常德</city>
		<city>张家界</city>
		<city>益阳</city>
		<city>郴州</city>
		<city>永州</city>
		<city>怀化</city>
		<city>娄底</city>
		<city>湘西</city>
	</province>
	<province name="广东">
		<city>广州</city>
		<city>韶关</city>
		<city>深圳</city>
		<city>珠海</city>
		<city>汕头</city>
		<city>佛山</city>
		<city>江门</city>
		<city>湛江</city>
		<city>茂名</city>
		<city>肇庆</city>
		<city>惠州</city>
		<city>梅州</city>
		<city>汕尾</city>
		<city>河源</city>
		<city>阳江</city>
		<city>清远</city>
		<city>东莞</city>
		<city>中山</city>
		<city>潮州</city>
		<city>揭阳</city>
		<city>云浮</city>
	</province>
	<province name="广西">
		<city>南宁</city>
		<city>柳州</city>
		<city>桂林</city>
		<city>梧州</city>
		<city>北海</city>
		<city>防城港</city>
		<city>钦州</city>
		<city>贵港</city>
		<city>玉林</city>
		<city>百色</city>
		<city>贺州</city>
		<city>河池</city>
		<city>来宾</city>
		<city>崇左</city>
	</province>
	<province name="海南">
		<city>海口</city>
		<city>三亚</city>
	</province>
	<province name="重庆">
		<city>重庆</city>
		<city>万州区</city>
		<city>涪陵区</city>
		<city>渝中区</city>
		<city>大渡口区</city>
		<city>江北区</city>
		<city>沙坪坝区</city>
		<city>九龙坡区</city>
		<city>南岸区</city>
		<city>北碚区</city>
		<city>万盛区</city>
		<city>双桥区</city>
		<city>渝北区</city>
		<city>巴南区</city>
		<city>黔江区</city>
		<city>长寿区</city>
		<city>綦江县</city>
		<city>潼南县</city>
		<city>铜梁县</city>
		<city>大足县</city>
		<city>荣昌县</city>
		<city>璧山县</city>
		<city>梁平县</city>
		<city>城口县</city>
		<city>丰都县</city>
		<city>垫江县</city>
		<city>武隆县</city>
		<city>忠县</city>
		<city>开县</city>
		<city>云阳县</city>
		<city>奉节县</city>
		<city>巫山县</city>
		<city>巫溪县</city>
		<city>石柱土家族自治县</city>
		<city>秀山土家族苗族自治县</city>
		<city>酉阳土家族苗族自治县</city>
		<city>彭水苗族土家族自治县</city>
		<city>江津</city>
		<city>合川</city>
		<city>永川</city>
		<city>南川</city>
	</province>
	<province name="四川">
		<city>成都</city>
		<city>自贡</city>
		<city>攀枝花</city>
		<city>泸州</city>
		<city>德阳</city>
		<city>绵阳</city>
		<city>广元</city>
		<city>遂宁</city>
		<city>内江</city>
		<city>乐山</city>
		<city>南充</city>
		<city>眉山</city>
		<city>宜宾</city>
		<city>广安</city>
		<city>达州</city>
		<city>雅安</city>
		<city>巴中</city>
		<city>资阳</city>
		<city>阿坝</city>
		<city>甘孜</city>
		<city>凉山</city>
	</province>
	<province name="贵州">
		<city>贵阳</city>
		<city>六盘水</city>
		<city>遵义</city>
		<city>安顺</city>
		<city>铜仁</city>
		<city>黔西南</city>
		<city>毕节</city>
		<city>黔东南</city>
		<city>黔南</city>
	</province>
	<province name="云南">
		<city>昆明</city>
		<city>曲靖</city>
		<city>玉溪</city>
		<city>保山</city>
		<city>昭通</city>
		<city>丽江</city>
		<city>思茅</city>
		<city>临沧</city>
		<city>楚雄</city>
		<city>红河</city>
		<city>文山</city>
		<city>西双版纳</city>
		<city>大理</city>
		<city>德宏</city>
		<city>怒江</city>
		<city>迪庆</city>
	</province>
	<province name="西藏">
		<city>拉萨</city>
		<city>昌都</city>
		<city>山南</city>
		<city>日喀则</city>
		<city>那曲</city>
		<city>阿里</city>
		<city>林芝</city>
	</province>
	<province name="陕西">
		<city>西安</city>
		<city>铜川</city>
		<city>宝鸡</city>
		<city>咸阳</city>
		<city>渭南</city>
		<city>延安</city>
		<city>汉中</city>
		<city>榆林</city>
		<city>安康</city>
		<city>商洛</city>
	</province>
	<province name="甘肃">
		<city>兰州</city>
		<city>嘉峪关</city>
		<city>金昌</city>
		<city>白银</city>
		<city>天水</city>
		<city>武威</city>
		<city>张掖</city>
		<city>平凉</city>
		<city>酒泉</city>
		<city>庆阳</city>
		<city>定西</city>
		<city>陇南</city>
		<city>临夏</city>
		<city>甘南</city>
	</province>
	<province name="青海">
		<city>西宁</city>
		<city>海东</city>
		<city>海北</city>
		<city>黄南</city>
		<city>海南</city>
		<city>果洛</city>
		<city>玉树</city>
		<city>海西</city>
	</province>
	<province name="宁夏">
		<city>银川</city>
		<city>石嘴山</city>
		<city>吴忠</city>
		<city>固原</city>
		<city>中卫</city>
	</province>
	<province name="新疆">
		<city>乌鲁木齐</city>
		<city>克拉玛依</city>
		<city>吐鲁番</city>
		<city>哈密</city>
		<city>昌吉</city>
		<city>博尔塔拉</city>
		<city>巴音郭楞</city>
		<city>阿克苏</city>
		<city>克孜勒苏</city>
		<city>喀什</city>
		<city>和田</city>
		<city>伊犁</city>
		<city>塔城</city>
		<city>阿勒泰</city>
		<city>石河子</city>
		<city>阿拉尔</city>
		<city>图木舒克</city>
		<city>五家渠</city>
	</province>
	<province name="香港">
		<city>香港</city>
	</province>
	<province name="澳门">
		<city>澳门</city>
	</province>
	<province name="台湾">
		<city>台湾</city>
	</province>
</china>

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值