举个栗子,用户注册的时候填写了表单信息,希望能及时看到用户名是否可用并且如果用户名要是不可用的话,表单不提交,原来的信息还在页面中,这时就需要隐藏帧技术了,也就是Ajax的底层原理。

写一个简单的注册页面

隐藏帧技术(Ajax底层原理)_Ajax底层

    

隐藏帧技术(Ajax底层原理)_html_02

步骤大概是这样的:

隐藏帧技术(Ajax底层原理)_html_03

然后就是代码:

1.注册页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册页面</title>

<script type="text/javascript">
function checkAll(){
return isNameOk && checkName() && checkPwd();
}
/* 2.将用户名文本框中的内容赋值到隐藏小表单中,并且提交这个小表单 */
function checkName(){
document.getElementById("valName").value = document.getElementById("name").value;
form2.submit();
}
function checkPwd(){
return true;
}
var isNameOk = false;//用户名是否可用,如果不可用,阻止用户提交表单
/* 5.父窗口函数,控制用户名是否可用 */
function valNameAjax(res){
if(res==1){//已存在
msg.innerHTML="用户名已存在";
document.getElementById("name").focus();//焦点
}else if(res==0){//可用
msg.innerHTML="用户名可用";
isNameOk = true;
return ;
}
isNameOk = false;
}
</script>
</head>
<body>
<!-- 主表单 -->
<form action="${pageContext.request.contextPath}/aa" method="post" id="form1">
<!-- 1.用户填写用户名,焦点离开时文本框内容改变,调用checkName函数 -->
<input type="text" name="name" id="name" onchange="checkName(this)" placeholder="请输入用户名"/>
<label id="msg"></label><br><br>
<input type="password" name="pwd" onblur="checkPwd(this)" placeholder="请输入密码"/> <br><br>
<input type="submit" onclick="return checkAll()" value="提交"/>
</form>

<!-- 3.隐藏的小表单,提交这个表单到servlet,servlet的结果返回到frame中(这个是为了不让提交表单之后页面跳转) -->
<form action="${pageContext.request.contextPath}/myAjax" target="frame" method="post" id="form2">
<input type="hidden" name="valName" id="valName"/><br><br>
</form>

<!-- 坑!这里要使用name而不是id -->
<!-- 4.其实是res.jsp,在里面接收结果,然后在调用父窗口函数valNameAjax -->
<iframe name="frame" src="${pageContext.request.contextPath}/myAjax/res.jsp" style="display: none"></iframe>
</body>
</html>

2.res.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<script type="text/javascript">
var res = <%=request.getAttribute("res")%>
parent.valNameAjax(res);//调用父窗口函数
</script>
</body>
</html>

3.servlet

package cn.hncu.servlets;

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 MyAjaxServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("valName");
System.out.println("name:"+name);
//模拟数据库查询
if(name!=null && name.startsWith("bl")) {
request.setAttribute("res", 1);//已存在
}else {
request.setAttribute("res", 0);//用户名可用
}
request.getRequestDispatcher("/myAjax/res.jsp").forward(request,response);
}

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