隐藏帧技术原理:
随着HTML帧的引入,隐藏帧(hidden frame)技术也应运而生了。该技术后面的基本想法是创建一个帧集,其中包含用于客户端—服务器通信的隐藏帧。可以通过将帧的宽度或高度设置为0像素来隐藏一个帧,以使其不显示。尽管一些早期的浏览器(诸如Netscape 4)不能够完全隐藏帧,经常会留下一些明显的帧边框,但该技术还是广泛地为开发人员所采用。
过程图解:
关键代码:
index.jsp中关键的js代码
var isNameError = 1;
function checkName() {
isNameError = 1;
var oName = document.getElementsByName("name")[0];
var value = oName.value;
var reg = /^\w{3,10}$/;
var okMsg="";
var errorMsg="用户名由3~10个的字母、数字或_ 组成。".fontcolor("#f00");
var boo = check(reg,value,nameSpan,okMsg,errorMsg);
if( boo ){
//开始进行点通讯
//1.把oName.value赋给 '隐藏表单' 中的 input
document.getElementsByName("regName")[0].value=value;
//2.提交'隐藏表单'
hiddenForm.submit();
}else{
return false;
}
}
//该函数是回调函数,在jsps/checkResult.jsp中调用
function callBack(res) {
isNameError = res;
if ( isNameError == 0 ) {
nameSpan.innerHTML="恭喜,用户名可以使用。".fontcolor("#0f0");
} else {
nameSpan.innerHTML="用户名已存在,请换一个试一试。".fontcolor("#f00");
}
}
index.jsp中关键的html代码
<!-- 以下是隐藏帧技术需要的辅助元素 form和iframe 外加 一个/jsps/checkResult.jsp-->
<form id="hiddenForm" target="hiddenIframe" action="checkNameServlet" method="post">
<input type="hidden" name="regName" />
</form>
<iframe name="hiddenIframe" style="display: none;" >
</iframe>
CheckNameServlet中关键代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String regName = request.getParameter("regName");
//按理这里应该进行dao层查询,这里就模拟了
//假设hncu开头的才可以注册,其他的都不行
//响应 "0" 表示可以注册,响应 "1" 表示不可以注册
if( regName != null && regName.startsWith("hncu") ) {
request.setAttribute("error", 0); //隐藏帧技术--基础版
}else {
request.setAttribute("error", 1); //隐藏帧技术--基础版
}
request.getRequestDispatcher("/jsps/checkResult.jsp").forward(request, response);
}
checkResult.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">
<script type="text/javascript">
var res = <%=request.getAttribute("error")==null?"1":request.getAttribute("error")%>;
parent.callBack(res);
</script>
</head>
<body>
</body>
</html>
在上面的基础上,进行优化模拟ajax
思路:
不需要checkResult.jsp,而是在iframe上添加一个onload函数,当iframe接收完服务器响应时就会触发,触发后就调用回调函数即可实现类似ajax功能。
关键代码:
myAjax(json);函数
//需要传入一个JSON对象参数
function myAjax(json) {
//先获取辅助用的 '隐藏的iframe'
oIframe = document.getElementsByName("myAjax_hiddenIframe")[0];
//如果没有就产生一个iframe
if( !oIframe ){
//创建<iframe>元素
oIframe = document.createElement("iframe");
//设置 name 属性,以便与下面的<form>元素的target属性关联起来
oIframe.name="myAjax_hiddenIframe";
//设置<iframe>元素不显示
oIframe.style.display="none";
//绑定<iframe>接收到服务器响应后的响应事件
oIframe.onload = function(){
myAjaxIframeOnload(this,json["success"]);
};
//把<iframe>元素添加到document树上
document.body.appendChild(oIframe);
}
//先获取辅助用的 <form>元素
oForm = document.getElementById("myAjax_hiddenForm");
//判断是否为存在,不存在就生成一个<form>元素
if( !oForm ){
oForm = document.createElement("form");
oForm.id = "myAjax_hiddenForm"
oForm.method="post";
//下面这一句将form提交后响应目标窗口绑定到上面的iframe元素
oForm.target=oIframe.name;
//设置提交的url
oForm.action=json["url"];
}
//先清空oForm中的所有内容
oForm.innerHTML="";
//获取需要向后台提交的数据
var data = json["data"];
//遍历data-->json对象
for( var x in data){
oForm.innerHTML += "<input type='hidden' name='"+x+"' value='"+data[x]+"' />"
}
//把<form>元素添加到document树上
document.body.appendChild(oForm);
//提交表单
oForm.submit();
}
function myAjaxIframeOnload(oIframe, method ){
var iframeDom = oIframe.contentWindow.document;
//alert(iframeDom.body.innerHTML);
//通过alert可以测试不同浏览器的弹框内容,根据具体内容做浏览器兼容
var iPre = iframeDom.getElementsByTagName("pre")[0];
if(iPre){//chrome 和 Firefox
method( iPre.innerHTML );
}else{//IE
method( iframeDom.body.innerHTML );
}
}
调用:
function checkName() {
isNameError = 1;
var oName = document.getElementsByName("name")[0];
var value = oName.value;
var reg = /^\w{3,10}$/;
var okMsg="";
var errorMsg="用户名由3~10个的字母、数字或_ 组成。".fontcolor("#f00");
var boo = check(reg,value,nameSpan,okMsg,errorMsg);
if( boo ){
myAjax({
"url":"checkNameServlet",
"data":{
"regName":value
},
"success":function(data){
callBack(data);
}
});
}else{
return false;
}
}
CheckNameServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String regName = request.getParameter("regName");
//按理这里应该进行dao层查询,这里就模拟了
//假设hncu开头的才可以注册,其他的都不行
//响应 "0" 表示可以注册,响应 "1" 表示不可以注册
if( regName != null && regName.startsWith("hncu") ) {
response.getWriter().println("0"); //myAjax版
} else {
response.getWriter().println("1"); //myAjax版
}
}