今天学习了不用ajax,实现注册表单向后台判断用户名是否存在的隐藏帧技术,
也是ajax的底层原型技术。
首先,如下图所示,界面是由注册表单、小表单以及一个iframe组成。后台是一个
处理注册的Servlet以及判断用户名是否存在的servlet取名为valNameServlet。
隐藏之后的页面;
技术细节:
1.小表单的type为hidden,并设置一个target属性将访问servlet的结果响应到iframe中
<!--专用于向后台提交"name"的小表单 -->
<form target="dataFrm" id="fm2" action="servlet/valNameServlet" method="post">
<input id="regName" type="hidden" name="regName" />
</form>
2.iframe使用的是name属性而不是id属性,iframe的作用相当于ajax的回调。
<!-- 注意,iframe中是name属性,不是id属性 -->
<iframe name="dataFrm" style="display: none;"></iframe>
3.js即通过点通讯将表单提交后台,并返回结果:
//与后台进行点通讯的前端页面技术
function valName(obj){
//var name = document.getElementsByName("name")[0].value; //如果函数没有传this参数
//alert(name);
var name = obj.value; //如果函数传了this参数
//要把name发给后台校验并接收校验结果
if(name!=null){
//把name填入小表单,提交小表单
document.getElementById("regName").value=name;
fm2.submit();
}
}
var isNameError="1";
function returnBack(res){
isNameError=res;
if(res=="1"){
document.getElementById("msg").innerHTML="该用户名已经被注册,请换一个!";
}else{
document.getElementById("msg").innerHTML="恭喜,该用户名可以使用!";
}
}
4.如何将传到的iframe中的结果传回到父页面即注册表单:
1.在js中读取后台servlet中传过来的数据方法 :
var res='<%=request.getAttribute("error")%>';
2.直接调用父页中的一个函数:parent.returnBack(res); 这一行代码的作用就是
从iframe中将结果传参到父页面即index.jsp,然后index.jsp再通过传回来的结果
进行判断并显示。
以下是代码:
前端index页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>隐藏帧技术---ajax的底层原型技术</title>
<script type="text/javascript">
//与后台进行点通讯的前端页面技术
function valName(obj){
//var name = document.getElementsByName("name")[0].value; //如果函数没有传this参数
//alert(name);
var name = obj.value; //如果函数传了this参数
//要把name发给后台校验并接收校验结果
if(name!=null){
//把name填入小表单,提交小表单
document.getElementById("regName").value=name;
fm2.submit();
}
}
var isNameError="1";
function returnBack(res){
isNameError=res;
if(res=="1"){
document.getElementById("msg").innerHTML="该用户名已经被注册,请换一个!";
}else{
document.getElementById("msg").innerHTML="恭喜,该用户名可以使用!";
}
}
下面这些函数的技术我们之前已经讲过,不属本次课的内容//
function sub(){
if(isNameError=="0" && valQq() && valEmail() && valPwd() ){
fm1.submit();
}
}
function valQq(){
//前端正则校验----略
return true;
}
function valPwd(){
//前端正则校验----略
return true;
}
function valEmail(){
//前端正则校验----略
return true;
}
</script>
</head>
<h1>隐藏帧技术---ajax的底层原型技术</h1>
<form id="fm1" action="RegServlet" method="post">
Name: <input type="text" name="name" onblur="valName(this);"/>
<label style="color:red;" id="msg"></label><br>
Pwd: <input type="password" name="pwd" onblur="valPwd();"/> <br>
QQ: <input type="text" name="qq" onblur="valQq();"/> <br>
Email: <input type="text" name="email" onblur="valEmail();"/> <br>
<input type="button" onclick="sub();" value="注册" />
</form>
<!--专用于向后台提交"name"的小表单 -->
<form target="dataFrm" id="fm2" action="servlet/valNameServlet" method="post">
<input id="regName" type="hidden" name="regName" />
</form>
<!-- 注意,iframe中是name属性,不是id属性 -->
<iframe name="dataFrm" style="display: none;"></iframe>
<body>
</body>
</html>
valnameServlet:
package cn.hncu.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class valNameServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
request.setCharacterEncoding("UTF-8");
String regName = request.getParameter("regName");
//按理这里应该调用dao层验证regName是否存在,这里模拟了...
/* 法1: 该方式只能向客户端输出简单的文本信息,无法执行js
response.setContentType("text/html;charset=utf-8");
if(regName!=null && regName.startsWith("hncu")){
response.getWriter().println("该用户名已经被注册,请换一个!");
}else{
response.getWriter().println("恭喜,该用户名可以使用!");
}
*/
/*法2: 转发到一个结果页面res.jsp,
* 让该res.jsp页面在iframe中显示,
* 同时在res.jsp页面中直接写一行打开页面就执行的js脚本。
*/
if(regName!=null && regName.startsWith("hncu")){
request.setAttribute("error", "1");//已经存在,error
}else{
request.setAttribute("error", "0"); //可以使用,ok
}
request.getRequestDispatcher("/jsps/res.jsp").forward(request, response);
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
}
res.jsp(iframe中的结果显示):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax后台返回后的结果页面</title>
<script type="text/javascript">
//alert("aaa...");
//给父页中的msg-label组件填写信息
//※知识点:如何在js中读取后台servlet中传过来的数据 ※//
var res='<%=request.getAttribute("error")%>';
/* 法1: 直接在子页中操纵父页中的文档元素---如果操作比较简单,这种方法还是可以的
if (res == 1) {
parent.document.getElementById("msg").innerHTML = "该用户名已经被注册,请换一个!";
} else {
parent.document.getElementById("msg").innerHTML = "恭喜,该用户名可以使用!";
}*/
//法2: 直接调用父页中的一个函数,让该函数操作---如果操作比较复杂,这种方法更好
parent.returnBack(res);
</script>
</head>
<body>
<h2>ajax后台返回后的结果页面</h2>
<h3>你回来了....</h3>
</body>
</html>