J2EE下使用AJAX(四) 隐藏帧 -- 史前的AJAX实现

在我们的第一个例子中,我使用XmlHttpRequest实现AJAX,我称之为原始的AJAX实现,那么,使用隐藏帧来实现AJAX,则可称之为史前的AJAX实现了。这是AJAX最早的实现方法,事实上,Google的主页及Gmail都是使用隐藏帧技术实现的AJAX。

隐藏帧技术描述如下:使用一个隐藏的frame/iframe,主页面发送请求时,指定返回页面为该隐藏帧,这样,整个页面就不会被刷新,然后,主页面到隐藏帧中去取得返回的数据并进行处理即可。

使用隐藏帧技术实现AJAX有如下好处:

  • 只需浏览器支持HTML 4即可,不须ActiveX之类的支持
  • 可以维护浏览器历史,用户仍然可以使用浏览器上的后退和前进按钮。

尤其是第2个优点,如果用户有很强烈的要求的话,使用隐藏帧几乎就成了惟一的选择(如果使用AJAX),曾经看到有人提出了在使用AJAX的情况下如何保持前进/后退按钮的功能,主要就是如可以时间键存储页面信息,JS代码写得繁复无比,并且也没有完全解决这个问题。呵呵,如果使用隐藏帧技术,就不用这么麻烦了。

使用隐藏帧的缺点是如果隐藏帧载入失败,用户得不到任何出错信息,调试起来会比较费力一点。

好了,言归正传,我使用隐藏帧技术实现前面例子的简单功能,根据页面传入的一个字符串参数后台生成一个字符串,并在前台显示,为了显示前进/后退按钮是可用的,我加了一个时间标记。

本例包含如下几个文件:

  • hidden_frame.jsp: 用于发送AJAX请求
  • ajax_callback.jsp: 用于隐藏帧,接收AJAX请求
  • HiddenFrameAjaxServlet.java: 后台的servlet类
  • web.xml

4.1 hidden_frame.jsp

<%@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding
="GB18030"
%>
<!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=GB18030">
<title>Insert title here</title>
</head>
<body>
<form name="form1">
    
<input type='button' value='Hello' onclick='hello()' /> 
</form>
<div id="div1"></div>
<iframe id="frame1" src="about:blank" width="0" height="0" style="display:none">
</iframe>
<script type="text/javascript">

function hello() 
{
    
var user = "London";
    
var hid_frame = document.getElementById("frame1");
    hid_frame.src 
= "HiddenFrameAjax.do?uname=" + user + "&reqid=" + Math.random();
    
}

 
function callbackAjax(msg) 
{
   document.getElementById(
"div1").innerHTML = msg;
}
 
</script> 
</body>
</html>

页面里我定义了一个iframe,使用CSS属性定义为隐藏,对于Firefox,仅设其高度和宽度为0是不够的,你会看到有一个小点,呵呵,不晓得Mozila这样的目的是啥。

4.2 ajax_callback.jsp

<%...@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding
="GB18030"
%>
<!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=GB18030">
<title>Insert title here</title>
</head>
<body>
<h1>aaa</h1>
<div id="div1">${uname}</div>
<script type="text/javascript">
window.onload 
= function()
{
    
var retstr = document.getElementById("div1").innerHTML;
    parent.callbackAjax(retstr);
}

</script>
</body>
</html>

这个页面功能更简单,用于接收请求结果,该页面是要放到隐藏帧中的。关键在于设定window.onload事件,在页面载入完成后调用父页面的响应函数callbackAjax。

4.3 HiddenFrameAjaxServlet.java

package lld.test.ajax;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HiddenFrameAjaxServlet extends HttpServlet
{
    
private static final long serialVersionUID = -595334169176542957L;

    @Override
    
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            
throws ServletException, IOException
    
{
        
this.doPost(req, resp);
    }


    @Override
    
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            
throws ServletException, IOException
    
{
        String uname 
= req.getParameter("uname");
        System.out.println(
"get uname = " + uname);
        String retstr 
= "Hello, " + uname + "" + (new Date());
        req.setAttribute(
"uname", retstr);
        req.getRequestDispatcher(
"/ajax_callback.jsp").forward(req, resp);
    }


}

这是用于处理请求的普通Servelt,与非AJAX的Servlet完全一样,这是与前几例不同的地方。使用隐藏帧,功夫全在前台javascript上,后台不用去操心。

4.4 web.xml

添加Servlet描述

<servlet>
    
<servlet-name>HiddenFrameAjax</servlet-name>
    
<servlet-class>lld.test.ajax.HiddenFrameAjaxServlet</servlet-class>
</servlet>

<servlet-mapping>
    
<servlet-name>HiddenFrameAjax</servlet-name>
    
<url-pattern>/HiddenFrameAjax.do</url-pattern>
</servlet-mapping>

4.5 Post方式

上例我是使用了Get方式发送请求,如果要使用post方式的话,只需要一个简单的小技巧,那就是使用form标签的target属性,将其设为隐藏帧即可。


还是那句话, 如果哪位需要示例的完整代码, 可发送邮件至lldwolf@163.com
阅读更多
个人分类: JAVA
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭