02-Ajax-局部刷新技术

Ajax

Ajax:(Asynchronous JavaScript And XML)指异步 JavaScript 及 XML
不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术,是基于JavaScript、XML、HTML、CSS新用法

Ajax:只刷新局部页面的技术

  • JavaScript:更新局部的网页
  • XML:一般用于请求数据和响应数据的封装
  • XMLHttpRequest对象:发送请求到服务器并获得返回结果
  • CSS:美化页面样式
  • 异步:发送请求后不等返回结果,由回调函数处理结果

Ajax的应用

  • 搜索—地图
  • 校验—获取数据
  • 购物车:
  • 局部刷新

Ajax交互模型

传统的Web交互方式

Ajax的交互方式

Ajax关键技术点

XMLHttpRequest对象
  • XMLHttpRequest 对象
    • 所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。
    • XMLHttpRequest 用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
  • 创建 XMLHttpRequest 对象
    • 所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。
  • 创建 XMLHttpRequest 对象的语法:
    • variable=new XMLHttpRequest();
    • 老版本的 Internet Explorer (IE5 和 IE6)使用ActiveX 对象:
    • variable=new ActiveXObject("Microsoft.XMLHTTP");
  • 编写一个方法兼容各个主流浏览器:
function getXMLHttpRequest(){
    var xmlhttp;
    if(window.XMLHTTpRequest){
        xmlhttp = new XMLHTTpRequest();
    }else if(window.ActiveXObject){
        httpxml=new ActiveXObject("Microsoft.XMLHTTP");
    }
}
ajax引擎对象的常用方法:
  • open(get/post,url,async);//创建请求
  • send([string]);//发送请求,如果是post提交,它的参数只能在这个方法传到后台。
  • setRequestHeader("Content-type","application/x-www-form-urlencoded");//如果post提交要传递参数就要设置请求的头部信息。
  • onreadystatechange=function(){};//ajax的回调函数,知道请求和响应处理到哪一步的状态 。【回调函数:将一个函数作为参数传给另一个函数】
ajax引擎对象常用属性:
  • readyState=4;专门判断请求是否正常处理
  • status=200;服务器是否正常响应
  • responseText;接收字符串类型的响应数据
  • responseXML;接收xml类型的响应数据
XMLHttpRequest对象和服务器交换数据
  • 向服务器发送请求
    • 如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open()send() 方法:
    • open(method,url,async)请求的方法(get/post),请求的路径,是否异步(一般为true)
      • xmlhttp.open("GET","url",true);
    • send(string) string:仅用于 POST 请求
      • xmlhttp.send();
onreadystatechange 事件(回调函数)

当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
readyState 属性存有 XMLHttpRequest 的状态信息。

下面是 XMLHttpRequest 对象的三个重要的属性:

属性描述
onreadystatechange存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
readyState存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

readyState

  • 0: 请求未初始化
  • 1: 服务器连接已建立
  • 2: 请求已接收
  • 3: 请求处理中
  • 4: 请求已完成,且响应已就绪

status

  • 200: “OK”
  • 404: 未找到页面

如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。

用Get发送异步请求:

用于异步传参,参数长度较小;请求处理速度快;异步请求读取数据;

  • 优点:请求的速度快。
  • 缺点:参数在URL后面拼接,参数的长度有限制;请求数据先从后台缓存中读取数据,缓存中无数据才查询。
	eg:/*发送异步请求,判断用户名的存在性*/
			//1.创建ajax引擎对象
			var xhr;
			if (window.XMLHttpRequest) {//新浏览器
				xhr=new XMLHttpRequest();
			}else{//IE5,IE6
				xhr=new ActiveXObject("Microsoft.XMLHTTP");
			}
			
			//2.创建请求
			xhr.open("get","UserServlet?action=isUser&uname="+uname,true);
			
			//3.发送请求
			xhr.send();
			
			//4.调用回调函数根据状态接收结果
			xhr.onreadystatechange=function(){
				if(xhr.readyState==4&&xhr.status==200){
					//接收服务器的响应结果
					var result=xhr.responseText;
					if (result=="1") {
						document.getElementById("uname1").innerHTML="用户名已注册";
						document.getElementById("uname1").style.color="red";
					}else{
						document.getElementById("uname1").innerHTML="";
					}
				}
			}

用Post发送异步请求:

用于异步传参,参数长度过大;用异步请求对后台数据作更改。

  • 优点:参数的长度无限制;请求的数据都是从后台查询,无缓存。
  • 缺点:请求速度慢。
	eg:/*发送异步请求,判断用户名的存在性*/
			//1.创建ajax引擎对象
			var xhr;
			if (window.XMLHttpRequest) {//新浏览器
				xhr=new XMLHttpRequest();
			}else{//IE5,IE6
				xhr=new ActiveXObject("Microsoft.XMLHTTP");
			}
			
			//2.创建请求
			xhr.open("post","UserServlet",true);
			
			//post请求要传递参数,就要设置请求头部信息
			xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
			
			//3.发送请求
			xhr.send("action=isUser&uname="+uname);
			
			//4.调用回调函数根据状态接收结果
			xhr.onreadystatechange=function(){
				if(xhr.readyState==4&&xhr.status==200){
					//接收服务器的响应结果
					var result=xhr.responseText;
					if (result=="1") {
						document.getElementById("uname1").innerHTML="用户名已注册";
						document.getElementById("uname1").style.color="red";
					}else{
						document.getElementById("uname1").innerHTML="";
					}
				}
			}

代码

Ajax验证用户名的唯一性
  • 准备好测试的环境
  • 创建表单页面,用户名,密码
  • 为用户名文本框绑定失去焦点事件
  • 当触发焦点事件时,发送ajax异步请求,判断用户名的唯一性
  • 掌握ajax发送异步请求的步骤
  • 编写好后端的Servlet处理请求

register.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">

    var isOk = false;
	function myBlur(){
		var username = document.getElementById("username");
		var span     = document.getElementsByTagName("span")[0];
		var value = username.value;
		if(value.trim() == ""){
			span.innerHTML = "用户名不能为空";
			isOk = false;
			return;
		}
		
		debugger
		
		//ajax的异步操作步骤:
		//1.获取xml的请求对象
		var xmlHttp = new XMLHttpRequest();
		//2. 发送请求
		xmlHttp.open("get", "RegisterServlet?action=register&username="+username.value, true);
		xmlHttp.send();
		
		//3. 回调函数的处理
		xmlHttp.onreadystatechange = function(){
			/* 请求已完成,且响应已就绪 */
			if(xmlHttp.readyState==4){  
				/* 返回页面的响应码是否正常,200成功响应 */
				if(xmlHttp.status==200){
					var text = xmlHttp.responseText;
					if(text == 1){
						span.innerHTML = "已注册";
						isOk = false;
					}else if(text == 0){
						span.innerHTML = "恭喜可用";
						isOk = true;
					}
				}
			}
		}
	}
	
	function mySub() {
		return isOk;
	}
</script>
</head>
<body>
		<form action="RegisterServlet?action=list" onsubmit="return mySub()">
			用户名:<input type="text" name="username" id="username" onblur="myBlur()"><span></span><br/>
			密码:<input type="text" name="password"><br/>
			<input type="submit" value="提交">
		</form>
</body>
</html>

RegisterServlet

package com.qf.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 RegisterServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getParameter("action");
		if("register".equals(action)){
			String username = request.getParameter("username");
			if("zs".equals(username)){
				response.getWriter().write("1");  //回传状态值:1:表示已注册,0:表示注册成功s
			}else{
				//注册成功
				response.getWriter().write("0");
			}
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}
Ajax-级联效果

通过选择省从而关联出城市的数据

province.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 change(){
    	var province = document.getElementById("province");
    	var city = document.getElementById("city");
    	if(province.value==""){
    		city.innerHTML = "<option>-请选择-</option>";
    		return;
    	}
    	
    	//ajax的异步操作步骤:
		var xmlHttp = new XMLHttpRequest();
    	
    	xmlHttp.open("get","ProvinceServlet?action=change&province="+province.value,true);
    	xmlHttp.send();
    	
    	xmlHttp.onreadystatechange = function(){  //回调函数
    		if(xmlHttp.readyState==4){
    			if(xmlHttp.status==200){
    				/*方式1:后台拼标签内容:<option value="changsha">长沙</option>  */
    				//city.innerHTML = xmlHttp.responseText; 
    				
    				/*方式2:前端自己拼接 */
    				/* [{name:'长沙',value='changsha'},{...}] */
    				/* eval(""): 将字符串中的内容转为js代码执行  */
    				var arr = eval(xmlHttp.responseText); 
    				var text = "";
    				debugger
    				for(var i=0;i<arr.length;i++){
    					text += "<option value='"+arr[i].value+"'>"+arr[i].name+"</option>";
    				}
    				city.innerHTML = text;
    			}
    		}
    	}
    }
	
</script>
</head>
<body>
      
      <!-- 通过ajax异步刷新: -->
      <select name="province" id="province" onchange="change()">
        <option value="">-请选择-</option>
      	<option value="hunan">湖南</option>
      	<option value="hubei">湖北</option>
      </select>
      
      <select name="city" id="city">
		<option>-请选择-</option>
      </select>
      
</body>
</html>

准备的数据

package com.qf.entity;

/**
*City实体类
*/
public class City {
	private String value;   //存储城市的value: changsha
	private String name;    //存储城市的name:   长沙
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "City [value=" + value + ", name=" + name + "]";
	}
	public City(String value, String name) {
		super();
		this.value = value;
		this.name = name;
	}
	public City() {
		super();
		// TODO Auto-generated constructor stub
	}
	
}
package com.qf.db;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.qf.entity.City;

public class DBCenter {
	
	//准备省份对应的城市数据: map的key:省名  value:城市的集合
	
	public static Map<String, List<City>> map = new HashMap<>();
	static{
		List<City> list = new ArrayList<>();
		list.add(new City("changsha", "长沙"));
		list.add(new City("chenzhou", "郴州"));
		list.add(new City("xiangtan", "湘潭"));
		map.put("hunan", list);
		
		List<City> list2 = new ArrayList<>();
		list2.add(new City("wuhan", "武汉"));
		list2.add(new City("xiangyang", "襄阳"));
		map.put("hubei", list2);
		
		
	}
}

ProvinceServlet

alibaba的json解析包
fastjson-1.1.22.jar
中文过滤器
encoding.jar

package com.qf.servlet;

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

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

import com.alibaba.fastjson.JSON;
import com.qf.db.DBCenter;
import com.qf.entity.City;

public class ProvinceServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getParameter("action");
		if("change".equals(action)){
			//hunan,hubei
			String province = request.getParameter("province");
			
			List<City> list = DBCenter.map.get(province);
			
			//方式1: 后台拼接数据
/*			StringBuilder builder = new StringBuilder();
			for (City city : list) {
				builder.append("<option value='"+city.getValue()+"'>"+city.getName()+"</option>");
			}
			System.out.println(builder.toString());
			response.getWriter().write(builder.toString());*/
			
			//方式2:直接将List传出去
			//List转成json字符串:  [{name:'长沙',value='changsha'},{...}]
			System.out.println(JSON.toJSONString(list));
			response.getWriter().write(JSON.toJSONString(list));
		}
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		doGet(request, response);
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值