ajax [asynchronous javascript and xml ]
什么是ajax
是一种用来改善用户体验的技术,本质是利用浏览器提供的一个
特殊对象(ajax对象,即XMLHttpRequest对象)向服务器发送
异步请求,服务器返回部分数据,浏览器利用这些数据对当前页面
做部分更新,整个过程,页面无刷新,不打断用户的操作。
注:
异步请求,指的是当ajax对象发送请求时,浏览器不会销毁当
前页面,用户仍然可以对当前页面做其它操作。
如何获得ajax对象
function getXhr(){
var xhr = null;
if(window.XMLHttpRequest){
//非ie
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('MicroSoft.XMLHttp');
}
return xhr;
}
ajax对象的重要属性
1)onreadystatechange:绑订事件处理函数(用来处理 readystatechange事件)。
注:当readyState属性性发生了变化(比如从1变成了2),就会产生readystatechange事件。
2)readyState:有5个值(0,1,2,3,4),用来获得ajax对象与服务器
通信的进展。当这个值为4时,表示ajax对象已经获得了服务器
返回的所有的数据。
3)responseText:获得服务器返回的文本数据。
4)responseXML:获得服务器返回的xml数据。
5)status:获得服务器返回的状态码。
开发步骤
1. 获得ajax对象
function getXhr(){
var xhr = null;
if(window.XMLHttpRequest){
//非ie
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('MicroSoft.XMLHttp');
}
return xhr;
}
//也可以简写为如下
var xhr=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('MicroSoft.XMLHttp');
测试程序
<%@ page contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试页面</title>
<script src="${pageContext.request.contextPath }/js/ajax.js"></script>
</head>
<body>
<a href="javascript:alert(getXhr());">获得ajax对象</a>
</body>
</html>
测试结果
2. 发送请求。
get请求
xhr.open(请求类型,请求地址,true/false);
//true:异步请求
//false:同步请求(当ajax请求发送请求时,浏览器会锁定当前页面)
xhr.onreadystatechange=事件处理函数;
xhr.send(null);
//例如:
xhr.open('get','check?uname=sally',true);
xhr.onreadystatechange=handle;
xhr.send(null);
发送post请求
xhr.open('post','check.do',true);
xhr.setRequestHeader('content-type',
'application/x-www-form-urlencoded');
xhr.onreadystatechange = handle;
xhr.send('uname=sally");
//按照http协议要求,如果发送的是post请求,请求数据包里面应该包含有content-type消息头
//默认情况下,ajax对象在发送请求时,不会添加该消息头
3.编写服务器端的代码。
通常只需要返回部分数据
4.编写事件处理函数。
if(xhr.readyState == 4 &&
xhr.status == 200){
var txt = xhr.responseText;
}
用户名重复校验
Get请求案例
需求:get请求校验用户名注册时是否出现注册的用户名已注册的情况
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
function check(){
//获得ajax对象
var xhr=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('MicroSoft.XMLHttp');
//注册onreadystatechange,事件处理函数
xhr.onreadystatechange=function(){
//ajax状态码==4和响应状态码==200时进行处理
if(xhr.readyState==4&&xhr.status==200){
//responseText:获得返回的响应数据中的文本
var txt=xhr.responseText;
//处理响应结果
document.getElementById('msg').innerHTML=txt;
}
};
var uname=document.getElementById('uname').value;
/*
get请求时,请求实体拼接在请求地址后,用?隔开,键值对
格式:
uri?请求实体名称=请求值
*/
var uri='check?uname='+uname;
/*
xhr.open(请求方式(get/post),请求地址,是否是异步请求,默认ajax请求是异步请求).
所以可以简写为以下xhr.open(请求方式,请求地址);
*/
xhr.open('GET',encodeURI(uri));
//发送请求
xhr.send(null);
}
</script>
</head>
<body style="font-size:30px;">
<form action="" method="post">
<fieldset>
<legend>注册</legend>
用户名:<input id="uname" name="uname"
onblur="check();"/>
<span id="msg" style="color:red;"></span>
<br/>
密码:<input type="password" name="pwd"/><br/>
<input type="submit" value="确定"/>
</fieldset>
</form>
</body>
</html>
package web;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/check")
public class UserServlet extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置请求编码格式
req.setCharacterEncoding("UTF-8");
// 设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("UTF-8");
// 获取请求信息
String uname = req.getParameter("uname");
if ("sally".equals(uname)) {
resp.getWriter().println("改用户名已被注册!");
} else {
resp.getWriter().println(uname + "注册成功!");
}
}
}
maven项目依赖的jar包和tomcat插件
<!--添加tomcat插件 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<hostName>localhost</hostName>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- servlet的jar包依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- jsp的jar包依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<!-- jstl表达式 -->
<!-- https://mvnrepository.com/artifact/jstl/jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
测试
http://localhost:8080/ajax/regist.html
在用户名中输入sally,之后移开鼠标到密码输入框中,页面显示效果如下
在用户名中输入妞妞,之后移开鼠标到密码输入框中,页面显示效果如下
post请求案例
修改上述html页面代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
function check(){
//获得ajax对象
var xhr=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('MicroSoft.XMLHttp');
//注册onreadystatechange,事件处理函数
xhr.onreadystatechange=function(){
//ajax状态码==4和响应状态码==200时进行处理
if(xhr.readyState==4&&xhr.status==200){
//responseText:获得返回的响应数据中的文本
var txt=xhr.responseText;
//处理响应结果
document.getElementById('msg').innerHTML=txt;
}
};
var uname=document.getElementById('uname').value;
/*
get请求时,请求实体拼接在请求地址后,
格式:
uri?请求实名名称=请求值
post请求时,请求实体需要单独的发送
格式:
xhr.open('POST',uri);
*/
var uri='check';
/*
xhr.open(请求方式(get/post),请求地址,是否是异步请求,默认ajax请求是异步请求).
所以可以简写为以下xhr.open(请求方式,请求地址);
*/
xhr.open('POST',encodeURI(uri));
/* 设置content-type消息头,告诉服务器
浏览器对发送过来的数据如何编码(这儿
采用的是key=value形式进行编码) */
/*
默认情况下,ajax对象在发送请求时,不会添加该消息头
post请求,设置请求头
不设置请求头,参数值无法传递,后台接收不到传递的参数值
*/
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
/*发送请求*/
xhr.send('uname='+uname);
}
</script>
</head>
<body style="font-size:30px;">
<form action="" method="post">
<fieldset>
<legend>注册</legend>
用户名:<input id="uname" name="uname"
onblur="check();"/>
<span id="msg" style="color:red;"></span>
<br/>
密码:<input type="password" name="pwd"/><br/>
<input type="submit" value="确定"/>
</fieldset>
</form>
</body>
</html>
测试
http://localhost:8080/ajax/regist.html
在用户名中输入sally,之后移开鼠标到密码输入框中,页面显示效果如下
在用户名中输入妞妞,之后移开鼠标到密码输入框中,页面显示效果如下
缓存问题
什么是缓存问题
ie浏览器提供的ajax对象在发送get请求时,会比较请求地址,如果访问过,则不再发送新的请求,而是显示之前访问的结果(会将第一次访问的结果缓存下来)。
解决
在请求地址后面添加一个随机数。
随机数
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
function getNumber() {
//获得ajax对象
var xhr = window.XMLHttpRequest ? new XMLHttpRequest(): new ActiveXObject('MicroSoft.XMLHttp');
//注册onreadystatechange,事件处理函数
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
//获取响应数据
var txt = xhr.responseText;
//处理响应
document.getElementById('msg').innerHTML = '随机数为:'+txt;
}
};
//发送请求
var uri = 'getNumber?r=' + Math.random();
xhr.open('GET', encodeURI(uri));
xhr.send(null);
}
</script>
</head>
<body style="font-size:20px;">
<a href="javascript:getNumber();">点这儿,显示一个随机整数</a>
<div id="msg"></div>
</body>
</html>
package web;
import java.io.IOException;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/getNumber")
public class RandomAction extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
resp.setCharacterEncoding("UTF-8");
Random r=new Random();
int random=r.nextInt(1000);
System.out.println(random);
resp.getWriter().println(random);
}
}
测试
http://localhost:8080/ajax/number.html
点击链接,效果如下
编码问题
发送get请求
a.为什么会有乱码?
ie所提供的ajax对象在发送请求时,会使用gbk编码,而其它
浏览器会使用utf-8来编码。
服务器端默认会使用iso-8859-1来解码,所以,会产生乱码。
b.如何解决?
step1.服务端统一使用utf-8来解码。
step2.在浏览器端,使用encodeURI函数对中文参数进行编码。
发送post请求
a.为什么会有乱码?
浏览器提供的ajax对象在发送请求时,会使用utf-8编码,
服务器端默认会使用iso-8859-1来解码,所以会产生乱码。
b.如何解决?
request.setCharacterEncoding(“utf-8”);
JSON
什么是JSON
一种轻量级的数据交换格式。
- 数据交换
将数据先转换成一种与平台无关的数据格式并发送给接收方来处理.
比如,将数据转换成xml文档然后发送给接收方来处理
2.轻量级
相对于xml而言,json文档更小,解析速度更快
基本语法
1)表示一个对象
{属性名:属性值,属性名:属性值…}
注:
a.属性名必须使用双引号括起来。
b.属性值可以是string,number,null,true/false,object。
c.属性值如果是string,必须使用双引号括起来。
2)表示由对象组成的数组
[{},{},…]
使用json交换数据
java对象转换成json字符串。
使用jackson提供的api(ObjectMapper)
maven项目依赖的jar包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<!--junit单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
java类
package pojo;
public class Stock {
private String code;
private String name;
private int price;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String toString() {
return "Stock [code=" + code + ", name=" + name + ", price=" + price + "]";
}
}
测试程序
package test;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import pojo.Stock;
public class TestCase {
/*
* 将java对象转换成json字符串
*/
@Test
public void test() throws JsonProcessingException {
Stock s = new Stock();
s.setCode("600877");
s.setName("中国嘉陵");
s.setPrice(9);
ObjectMapper orm=new ObjectMapper();
String str=orm.writeValueAsString(s);
System.out.println(str);
}
}
结果
将java对象组成的集合转换成json字符串
@Test
public void jsonArray() throws JsonProcessingException {
List<Stock> stocks = new ArrayList<Stock>();
Random r = new Random();
for (int i = 0; i < 3; i++) {
Stock s = new Stock();
s.setCode("60087" + r.nextInt(10));
s.setName("中国嘉陵" + r.nextInt(10));
s.setPrice(r.nextInt(1000));
stocks.add(s);
}
// 使用jackson提供的api来转换
ObjectMapper orm=new ObjectMapper();
String str=orm.writeValueAsString(stocks);
System.out.println(str);
}
结果:
json字符串转换成js对象
使用javascript内置的JSON的方法(parse)
使用json语法表示一个对象
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>json</title>
<script>
function f1() {
//使用json语法表示一个对象
var s = {
"code" : "600877",
"name" : "中国嘉陵",
"price" : 8
};
alert(s.name);
}
</script>
</head>
<body>
<a href="javascript:f1();">Clike me</a>
</body>
</html>
测试
点击链接,弹出对象的属性
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>json</title>
<script>
function f2(){
var obj={
"name":"呼呼",
"address":{
"city":"北京",
"street":"北三环西路",
"room":304
}
};
alert(obj.address.city);
}
</script>
</head>
<body>
<a href="javascript:f2();">Clike me</a>
</body>
</html>
测试
使用json语法表示由对象组成的数组
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>json</title>
<script>
function f3(){
//使用json语法表示由对象组成的数组
var arr=[
{
"name":"悟空",
"salary":1000
},
{
"name":"八戒",
"salary":800
}
];
alert(arr[1].salary);
}
</script>
</head>
<body>
<a href="javascript:f3();">Clike me</a>
</body>
</html>
测试
将json字符串转换成js对象
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>json</title>
<script>
function f3(){
//将json字符串转换成js对象
var str = '{"name":"悟空","salary":1000}';
//使用js内置对象JSON的parse方法来转换
var obj=JSON.parse(str);
alert(obj.name);
}
</script>
</head>
<body>
<a href="javascript:f3();">Clike me</a>
</body>
</html>
测试
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>json</title>
<script>
function f3(){
//将json字符串转换成js对象
var str = '[{"name":"悟空","salary":1000},'+'{"name":"八戒","salary":800}]';
//使用js内置对象JSON的parse方法来转换
var obj=JSON.parse(str);
alert(obj[1].name);
}
</script>
</head>
<body>
<a href="javascript:f3();">Clike me</a>
</body>
</html>
测试