应用场景
有的时候,我们需要让本次的响应内容和下一次响应的内容,同时展示给客户端。使用Ajax就可以在当前的网页显示响应post
请求内容。
简单实例
假如有这样的页面:
<input type="button" onclick="getData()" value="测试Ajax请求"/>
<div id="showDiv">
</div>
那么我的js是直接写死的修改div中的数据:
var getData = function(){
var sd = document.getElementById("showDiv");
sd.innerHTML="嘿嘿";
}
假如这个嘿嘿
的字段是从后台动态获取的,那么如何实现呢?
var getData = function(){
//创建Ajax引擎对象
var ajax;
if(window.XMLHttpRequest){
//FireFox(火狐浏览器)
ajax = new XMLHttpRequest();
}else if(window.ActiveXObject){
//IE(IE浏览器)
ajax = new ActiveXObject("Msxml2.XMLHTTP");
}
//复写onReadyStatement()
ajax.onreadystatechange = function(){
//状态函数会被触发4次,所以需要判断状态码
if(ajax.readyState==4){
//处理响应内容
var result = ajax.responseText;
var sd = document.getElementById("showDiv");
sd.innerHTML=result;
}
}
//打开链接
ajax.open("get","ajax");
//发送请求
ajax.send(null);
}
然后配置ajax的Servlet:
import java.io.IOException;
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("/ajax")
public class A extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
//设置请求响应编码的格式
res.setCharacterEncoding("utf-8");
res.setContentType("text/html;charset=utf-8");
//处理请求信息
res.getWriter().write("我是处理Ajax请求的数据");
}
}
注意:这么写其实还不够完善,因为,当我们的响应是错误的,例如404的时候,那么页面必然显示404啊,这样的用户体验极差,所以我门还需要判断相应的状态码。
//复写onReadyStatement()
ajax.onreadystatechange = function(){
//状态函数会被触发4次,所以需要判断状态码
if(ajax.readyState==4){
//判断响应的状态码
if(ajax.status==200){
//处理响应内容
var result = ajax.responseText;
var sd = document.getElementById("showDiv");
sd.innerHTML=result;
}
}
}
这样就可以了,除此之外,还可以加一些其他的处理方式。
异步和同步
首先假设我们的代码是这个样子的:
var getData = function(){
//创建Ajax引擎对象
var ajax;
if(window.XMLHttpRequest){
//FireFox(火狐浏览器)
ajax = new XMLHttpRequest();
}else if(window.ActiveXObject){
//IE(IE浏览器)
ajax = new ActiveXObject("Msxml2.XMLHTTP");
}
//复写onReadyStatement()
ajax.onreadystatechange = function(){
//状态函数会被触发4次,所以需要判断状态码
if(ajax.readyState==4){
//判断响应的状态码
if(ajax.status==200){
//处理响应内容
var result = ajax.responseText;
var sd = document.getElementById("showDiv");
sd.innerHTML=result;
//注意这里的Alert
alert(result);
}
}
}
//打开链接
ajax.open("get","ajax");
//发送请求
ajax.send(null);
//先编写一个Alert
alert("我是一个Alert");
这里我写了两个Alert打印相关信息,由于ajax默认是异步的,那么我们打开浏览器访问的时候,必然是先弹出result
的内容,然后才是最下面的我是一个Alert
的对话框。
梳理一下:
-
ajax.open("get","ajax",true);
:true表示异步,先弹出对话框我是一个Alert
-
ajax.open("get","ajax",false);
:false表示同步,后弹出对话框我是一个Alert
实现一个进度条
首先我们自己随便弄个图片:
然后修改一下我们的ajax请求:
var getData = function(){
//创建Ajax引擎对象
var ajax;
if(window.XMLHttpRequest){
//FireFox(火狐浏览器)
ajax = new XMLHttpRequest();
}else if(window.ActiveXObject){
//IE(IE浏览器)
ajax = new ActiveXObject("Msxml2.XMLHTTP");
}
//复写onReadyStatement()
ajax.onreadystatechange = function(){
//状态函数会被触发4次,所以需要判断状态码
if(ajax.readyState==4){
//判断响应的状态码
if(ajax.status==200){
//处理响应内容
var result = ajax.responseText;
var sd = document.getElementById("showDiv");
sd.innerHTML=result;
}
}else{
var sd = document.getElementById("showDiv");
//插入进度条图片
sd.innerHTML="<img src='img/2.png' width='100px' height='100px'/>";
}
}
//打开链接
ajax.open("get","ajax");
//发送请求
ajax.send(null);
}
为了让这个效果比较明显,我们还需要在Servlet当中沉睡3秒。
那么我们运行起来的效果:
然后过一段时间就能打印信息啦。
请求方式
- get请求:请求实体放在URL后面
- post请求:有单独的请求实体
首先编写一下处理get请求的代码:
package jxb.ajax;
import java.io.IOException;
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("/ajax")
public class A extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
System.out.println("处理啦请求编码");
req.setCharacterEncoding("utf-8");
//设置请求响应编码的格式
res.setCharacterEncoding("utf-8");
res.setContentType("text/html;charset=utf-8");
//处理请求信息
res.getWriter().write(req.getParameter("name")+":"+req.getParameter("pass"));
}
}
然后是ajax的代码:
var getData = function(){
//创建Ajax引擎对象
var ajax;
if(window.XMLHttpRequest){
//FireFox(火狐浏览器)
ajax = new XMLHttpRequest();
}else if(window.ActiveXObject){
//IE(IE浏览器)
ajax = new ActiveXObject("Msxml2.XMLHTTP");
}
//复写onReadyStatement()
ajax.onreadystatechange = function(){
//状态函数会被触发4次,所以需要判断状态码
if(ajax.readyState==4){
//判断响应的状态码
if(ajax.status==200){
//处理响应内容
var result = ajax.responseText;
var sd = document.getElementById("showDiv");
sd.innerHTML=result;
alert(result);
}
}
}
//GET方式请求:
ajax.open("get","ajax?name=张三&pass=123");
//发送请求
ajax.send(null);
}
我们仔细看一下get请求:
//GET方式请求:
ajax.open("get","ajax?name=张三&pass=123");
//发送请求
ajax.send(null);
因为get请求的参数是拼接在url后面的,所以send(null)即可,但是post请求的实体必须要单独send:
//Post方式:
ajax.open("post","ajax");
//设置请求实体的格式为键值对
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//Post请求实体需要单独发送:
ajax.send("name=张三&pass=123");
这就是唯一的一点差别。
Json格式的数据响应
当我们需要从后台获取对象的时候,可以使用json的格式把对象存成一个字符串,这里需要用到一个叫做gson.jar
的工具包,然后在前端js收到这个字符串后使用eval(string)
转成对象,然后使用dom元素操作,把对象中的数据插入到界面元素中。
如下是核心部分源码:
前端js代码:
XML格式的数据
做XML格式数据处理的时候,需要先把响应的格式修改为setContentType("text/xml;charset=utf-8")
:
然后需要在前端js中的响应改写为
ajax.responseXML
xml响应:
function getXML() {
//创建ajax引擎对象
var ajax;
if (window.XMLHttpRequest) {//火狐
ajax = new XMLHttpRequest();
} else if (window.ActiveXObject) {//ie
ajax = new ActiveXObject("Msxml2.XMLHTTP");
}
//复写onreadystatechange
ajax.onreadystatechange = function() {
//判断Ajax状态吗
if (ajax.readyState == 4) {
//判断响应状态吗
if (ajax.status == 200) {
//获取响应内容
var doc = ajax.responseXML;
//处理响应内容
//获取元素对象
alert(doc.getElementsByTagName("name")[0].innerHTML);
}
}
}
//发送请求
ajax.open("get", "xml.jsp", true);
ajax.send(null);
}
ajax.responseXML
返回的是一个document
对象,然后我们可以直接使用getElementsByTagName()
获取元素的数组。