1. 同步交互与异步交互
1.1 同步交互
- 客户端发送一个请求, 需要等待服务器的响应结束,才能发送第二个请求!
- 刷新的是整个页面.
1.2 异步交互
- 客户端发送一个请求,无需等待服务器的响应,然后就可以发送第二个请求!
- 可以使用 js 接收服务器的响应,然后使用 js 来局部刷新.
2. AJAX 概述
- AJAX: ansynchronous javascript and xml, 异步的 js 和 xml;
- 它能使用 js 访问服务器,而且是异步访问!
- 通常服务器给客户端响应的是一个完整的 html 页面!但在 ajax 中因为是局部刷新,那么服务器就不用
再响应整个页面,而只是数据,其中的数据格式包括:- text: 纯文本;
- xml
- json: js 提供的数据交换模式.
3. ajax 的优缺点
3.1 优点:
- 异步交互: 增强了用户体验!
- 性能: 因为服务器无需再响应整个页面, 只需要响应部分内容,所以服务器的压力减轻了.
3.2 缺点
- ajax 不能应用在所有场景;
- ajax 无端增多了对服务器的访问次数,给服务器带来了压力.
4. ajax 发送异步请求(四步操作)
第一步,得到 XMLHttpRequest 对象
- 大多数浏览器都支持:
var xmlHttp = new XMLHttpRequest();
- IE 6.0 :
var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
- IE 5.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){
throw e;
}
}
}
}
第二步, 打开与服务器的连接
xmlHttp.open()
: 用来打开与服务器的连接, 它需要三个参数:- 请求方式: GET 或 POST;
- 请求的 URL: 指定服务器端的资源, 例如:
/day23_1/AServlet
; - 请求是否为异步: 如果为 true,表示发送异步请求, 否则为同步请求!
- 示例:
xmlHttp.open("GET","/day23_1/AServlet",true);
第三步, 发送请求
xmlHttp.send(null)
: 必须带参数 null, 如果不给参数, 可能会造成 FireFox 浏览器无法发送!- 参数: 就是请求体的内容. 如果是 GET 请求,没有请求体,但必须给出 null.
第四步, 接收响应
- 在 xmlHttp 对象的一个事件上注册监听器:
onreadystatechange
. - xmlHttp 对象一共有五种状态:
- 0: 初始化未完成状态,只是创建了 XMLHttpRequest 对象,还未调用 open() 方法;
- 1: 请求已开始, open()方法已调用, 但还没调用 send() 方法;
- 2: 请求发送完成状态, send() 方法已调用;
- 3: 服务器已经开始响应, 但不表示响应结束了;
- 4: 服务器响应结束.(通常我们只关心这个状态!!!)
//得到 xmlHttp 对象的状态, 可能结果: 0, 1, 2, 3, 4
var state = xmlHttp.readyState;
// 得到服务器响应的状态码, 可能结果: 200, 404, 500
var status = xmlHttp.status;
// 得到服务器响应的内容
// var content = xmlHttp.responseText; // 得到服务器响应的文本格式的内容
// var content = xmlHttp.responseXML; // 得到服务器响应的 xml 格式的内容, 它是 document 对象
// 注册监听器
xmlHttp.onreadystatechange = function(){
// 双重判断
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
// 获取服务器的响应内容
var text = xmlHttp.responseText;
}
}
5. ajax 示例
// 示例一: 发送 POST 请求
<html>
<head>
<script type="text/javascript">
function createXMLHttpRequest(){
try{
return new XMLHttpRequest();
}catch(e){
try{
return new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try{
return new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
throw e;
}
}
}
}
// html 页面加载完成后执行
window.onload = function(){
var btn = document.getElementById("btn");
btn.onclick = function(){
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("POST","<c:url value='/AServlet'/>",true);
// 设置 Conten-Type 请求头
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
// 发送请求时, 指定请求体
xmlHttp.send("username=zhangsan&password=123");
// 注册监听器
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var text = xmlHttp.responseText;
var h1 = document.getElementById("h1");
h1.innnerHTML = text;
}
};
}
}
</script>
</head>
<body>
<button id="btn">点击这里</button>
<h1 id="h1"></h1>
</body>
</html>
// 示例二: 响应内容为 xml 数据
// 服务端需要设置响应头: response.setContentType("text/xml;charset=utf-8");
// 客户端需要使用 var doc = xmlHttp.responseXML; 获取 Document 对象;
// xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student number="1001">
<name>zhangsan</name>
<age>23</age>
<sex>male</sex>
</student>
</students>
// a.jsp
<html>
</head>
window.onload = function(){
var btn = document.getElementById("btn");
btn.onclick = function(){
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("GET","<c:url value='/BServlet'/>",true);
xmlHttp.send(null);
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var doc = xmlHttp.responseXML;
var ele = doc.getElementsByTagName("student")[0];
var number = ele.getAttribute("number");
var name = ele.getElementsByTagName("name")[0].textContent;
var age = ele.getElementsByTagName("age")[0].textContent;
var sex = ele.getElementByTagName("sex")[0].textContent;
var text = number+":"+name+","+age+","+sex;
doc.getElementById("h1").innerHTML = text;
}
};
};
};
</head>
<body>
<button id="btn">点击这里</button>
<h1 id="h1"></h1>
</body>
</html>
示例三: 省市联动
5. 模拟 JQuery 的 AJAX 请求
//创建 request 对象
function createXMLHttpRequest(){
try{
return new XMLHttpRequest();
}catch(e){
try{
return ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try{
return ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
throw e;
}
}
}
}
function ajax(option){
/*
* 分析:
* 参数 option 对象需要具有如下内容:
* 请求方式 method,
* 请求的 URL url,
* 是否异步 asyn,
* 请求体 params,
* 回调方法 callback,
* 服务器响应数据转换成什么类型 type
*/
// 1. 得到 xmlHTTP
var xmlHttp = createXMLHttpRequest();
// 2. 打开连接
if(!option.method){ // 如果method参数不存在,默认为 GET 请求
option.method="GET";
}
if(option.asyn == undefined){ // 默认异步处理
option.asyn = true;
}
xmlHttp.open(option.method,option.url,option.asyn);
// 判断是否为 POST
if("POST" == option.method){
xmlHTTP.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
}
// 发送请求
xmlHttp.send(option.params);
// 注册监听
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var data;
// 获取服务器的响应数据,进行转换
if(!option.type){
data = xmlHttp.responseText;
} else if(option.type == "xml"){
data = xmlHttp.responseXML;
} else if(option.type == "text"){
data = xmlHttp.responseText;
} else if(option.type == "json"){
var text = xmlHttp.responseText;
data = eval("("+text+")");
}
// 执行回调方法
option.callback(data);
}
};
}
参考资料: