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);
}
}