首先要说的就是 ajax 是无法实现上传文件的,可以想一下ajax与后台通信都是通过传递字符串,怎么能传递文件呢?其实出于安全考虑js是不能操作文件的,所以就不要再说用ajax来实现文件的上传了,这是不可能的。 
    而本文实现的文件上传也是无页面刷新的,可以说是一种"类似AJAX"方法。 
    开始之前先说两句无关的,其实在ajax出现之前,web应用也可以是无刷新的,那时大多通过IFrame来做到这一点。当然Ajax出现之后,人们一窝蜂地投奔Ajax 的阵营了,iFrame 就乏人问津了。但是用iFrame来实现无刷新上传文件确实一个很好的选择。ps:Ajax技术基本上可以说是由google公司带起来的,但少Gmail中上传文件用的还是 IFrame,所以说使用IFrame来上传文件是最好的选择。 
    我在这里这里用的技术是jsp,其实asp,php等也是一样可以这么实现的 
    一共两个文件就可实现:index.html 和 upload.jsp,在这里讲解一下,文后会附上源码 --index.html 
html 代码 
Html代码 
<html>       
<body>       
      
<form action="upload.jsp" id="form1" name="form1" encType="multipart/form-data"  method="post" target="hidden_frame" >       
    <input type="file" id="file" name="file" style="width:450">       
    <INPUT type="submit" value="上传文件"><span id="msg"></span>       
    <br>       
    <font color="red">支持JPG,JPEG,GIF,BMP,SWF,RMVB,RM,AVI文件的上传</font>                     
    <iframe name='hidden_frame' id="hidden_frame" style='display:none'></iframe>       
</form>       
      
</body>       
</html>       
      
<script type="text/javascript">       
function callback(msg)       
{       
    document.getElementById("file").outerHTML = document.getElementById("file").outerHTML;       
    document.getElementById("msg").innerHTML = "<font color=red>"+msg+"</font>";       
}       
</script>     <html>    
<body>    
   
<form action="upload.jsp" id="form1" name="form1" encType="multipart/form-data"  method="post" target="hidden_frame" >    
    <input type="file" id="file" name="file" style="width:450">    
    <INPUT type="submit" value="上传文件"><span id="msg"></span>    
    <br>    
    <font color="red">支持JPG,JPEG,GIF,BMP,SWF,RMVB,RM,AVI文件的上传</font>                  
    <iframe name='hidden_frame' id="hidden_frame" style='display:none'></iframe>    
</form>    
   
</body>    
</html>    
   
<script type="text/javascript">    
function callback(msg)    
{    
    document.getElementById("file").outerHTML = document.getElementById("file").outerHTML;    
    document.getElementById("msg").innerHTML = "<font color=red>"+msg+"</font>";    
}    
</script>   index.html 中主要要做的就是写一个 form 和 iframe ,并把 form 的 target 设为 iframe 的名字,注意要把 iframe 设为不可见,其他的都是正常的文件上传的写法,这样刷新的页面就是这个隐藏的 Iframe ,而在 index.html 中是不会有页面刷新的,js的 callback 方法是回调方法。用于清空文件上传框和显示后台信息,注意清空文件上传框的方法,和普通方法有点不一样。 --upload.jsp Html代码 
  
jsp 代码   
<%@ page language="java" contentType="text/html; charset=gb2312" %>       
<%@ page import="com.jspsmart.upload.SmartUpload"%>       
      
<%       
    //新建一个SmartUpload对象       
    SmartUpload su = new SmartUpload();       
      
    //上传初始化       
    su.initialize(pageContext);       
      
    // 设定上传限制       
    //1.限制每个上传文件的最大长度。       
    su.setMaxFileSize(10000000);       
      
    //2.限制总上传数据的长度。       
    su.setTotalMaxFileSize(20000000);       
      
    //3.设定允许上传的文件(通过扩展名限制),仅允许doc,txt文件。       
    su.setAllowedFilesList("doc,txt,jpg,rar,mid,waw,mp3,gif");       
           
    boolean sign = true;       
           
    //4.设定禁止上传的文件(通过扩展名限制),禁止上传带有exe,bat,jsp,htm,html扩展名的文件和没有扩展名的文件。       
    try {       
        su.setDeniedFilesList("exe,bat,jsp,htm,html");       
      
        //上传文件       
        su.upload();       
        //将上传文件保存到指定目录       
        su.save("c:\\");      
     
    } catch (Exception e) {      
        e.printStackTrace();      
        sign = false;      
    }      
    if(sign==true)      
    {      
        out.println("<script>parent.callback('upload file success')</script>");      
    }else      
    {      
        out.println("<script>parent.callback('upload file error')</script>");       
    }       
%>      
jsp 代码
<%@ page language="java" contentType="text/html; charset=gb2312" %>    
<%@ page import="com.jspsmart.upload.SmartUpload"%>    
   
<%    
    //新建一个SmartUpload对象    
    SmartUpload su = new SmartUpload();    
   
    //上传初始化    
    su.initialize(pageContext);    
   
    // 设定上传限制    
    //1.限制每个上传文件的最大长度。    
    su.setMaxFileSize(10000000);    
   
    //2.限制总上传数据的长度。    
    su.setTotalMaxFileSize(20000000);    
   
    //3.设定允许上传的文件(通过扩展名限制),仅允许doc,txt文件。    
    su.setAllowedFilesList("doc,txt,jpg,rar,mid,waw,mp3,gif");    
        
    boolean sign = true;    
        
    //4.设定禁止上传的文件(通过扩展名限制),禁止上传带有exe,bat,jsp,htm,html扩展名的文件和没有扩展名的文件。    
    try {    
        su.setDeniedFilesList("exe,bat,jsp,htm,html");    
   
        //上传文件    
        su.upload();    
        //将上传文件保存到指定目录    
        su.save("c:\\");   
  
    } catch (Exception e) {   
        e.printStackTrace();   
        sign = false;   
    }   
    if(sign==true)   
    {   
        out.println("<script>parent.callback('upload file success')</script>");   
    }else   
    {   
        out.println("<script>parent.callback('upload file error')</script>");    
    }    
%>    
upload.jsp 中只要注意最后输出的格式就可以了。其实原理就是输出一段js代码到 iframe 中,然后在iframe中来控制它的父页面。     OK,至此一个无刷新的页面上传组件就做好了,不要忘了在 WEB-INF/lib 下加上必须的 jspSmartUpload.jar 包。 
    需要说明的是使用Iframe来上传,状态栏还是会有刷新的,因为iframe 中的页面刷新了嘛,但是外部页面,就是你所看到的页面是没有刷新的,所以也可以说是类似Ajax上传。 

解决方案 »

  1.   

    现在是AJAX横行的时代,也许已经很少有人用隐藏form提交来实现不刷新页面更新了。在AJAX以前,一般都是用隐藏form提交来实现页面不刷新提交数据,虽然那时候我也常用xmlhttp提交来实现,不过现在ajax概念流行,不用一下总好像你跟不上时代似的,老总会问“你用了ajax了没有”。现在来对比一下ajax与隐藏form提交的利与弊。1.隐藏form提交,更新数据完成后,需要转到一个空白页面再对原页面进行提交后处理;ajax则不用,可以直接返回原页面进行提交后的处理。可见ajax可以比隐藏form提交少增加一个页面。2.ajax出于安全性考虑,不能对文件进行操作,所以就不能通过ajax来实现文件上传,而通过隐藏form提交则可以实现这个功能,所以这就是目前用隐藏form提交的主要用途。现在接下来讲述如何通过隐藏form来实现文件上传 1)首先定义一个用于填写表单内容的form<form name="form1"></form>2)接着定义一个用于提交的form<form name="form2" target="myIframe">  //用于指定提交返回的页面显示在这个隐藏的iframe中<iframe name="myIframe" style="display:none"></iframe>  //用于存放提交返回后的空白页面<div id="formInner" style="display:none"></div>  //用于获取form1的html内容,获得form1的表单元素</form>3)在form1提交时,进行如下javascript处理var formInner= document.getElementById("formInner");
       formInner.innerHTML = form1.innerHTML;  //复制form1的html代码
       form2.action = form1.action;
       form2.submit();4)提交后,进入后台处理,后台处理完成后,需要返回一个空白页面blank.jsp,这个页面是在隐藏的iframe中生成的,所以可以通过parent对象对原页面进行操作。比如原页面定义了一个updatePageFromSubmit(),则在blank.jsp页面中可以通过parent.updatePageFromSubmit()来调用进行提交返回后 的处理
      

  2.   

    lib中导入jspSmartUpload.jar 上传文件 的页面 <!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"> 
    <title>upload file</title> 
    </head> 
    <body> <form action="upload.jsp" id="form1" name="form1" encType="multipart/form-data"  method="post" target="hidden_frame" > 
    <input type="file" id="file" name="file" style="width:450"> 
    <INPUT type="submit" value="上传文件"><span id="msg"></span> 
    <br> 
    <font color="red">支持JPG,JPEG,GIF,BMP,SWF,RMVB,RM,AVI文件的上传</font>              
    <iframe name='hidden_frame' id="hidden_frame" style='display:none'></iframe> 
    </form> </body> 
    </html> <script type="text/javascript"> 
    function callback(msg) 

    document.getElementById("file").outerHTML = document.getElementById("file").outerHTML; 
    document.getElementById("msg").innerHTML = "<font color=red>"+msg+"</font>"; 

    </script> ---------------------------------------------------------------------------------------------- <%@ page language="java" contentType="text/html; charset=gb2312" %> 
    <%@ page import="com.jspsmart.upload.SmartUpload"%> <% 
    //新建一个SmartUpload对象 
    SmartUpload su = new SmartUpload(); //上传初始化 
    su.initialize(pageContext); // 设定上传限制 
    //1.限制每个上传文件的最大长度。 
    su.setMaxFileSize(10000000); //2.限制总上传数据的长度。 
    su.setTotalMaxFileSize(20000000); //3.设定允许上传的文件(通过扩展名限制),仅允许doc,txt文件。 
    su.setAllowedFilesList("doc,txt,jpg,rar,mid,waw,mp3,gif"); boolean sign = true; //4.设定禁止上传的文件(通过扩展名限制),禁止上传带有exe,bat,jsp,htm,html扩展名的文件和没有扩展名的文件。 
    try { 
      su.setDeniedFilesList("exe,bat,jsp,htm,html");   //上传文件 
      su.upload(); 
      //将上传文件保存到指定目录 
      su.save("c:\\"); } catch (Exception e) { 
      e.printStackTrace(); 
      sign = false; 

    if(sign==true) 

      out.println("<script>parent.callback('upload file success')</script>");         //要返回的信息 
    }else 

      out.println("<script>parent.callback('upload file error')</script>"); 

    %> 
      

  3.   

    jspSmartUpload是一款免费且简单易用的上传下载组件,具有非常实用的价值,下面笔者通过一个简单的例子(如图1-1所示)对jspSmartUpload组件的使用一个简单的实现。                                                    图 1-1 添加商品信息将准备好的jspSmartUpload JAR包复制到项目WebRoot根目录下的WEB-INF目录的lib目录中。
     为表单添加属性“enctype”,其属性值为“multipart/form-data”,如下所示:Html代码 
    <form name="form1" method="post" action="doUpload.jsp" enctype="multipart/form-data"></form>  <form name="form1" method="post" action="doUpload.jsp" enctype="multipart/form-data"></form>
    执行代码:Java代码 
    <%   
    // 设置编码格式   
    request.setCharacterEncoding(“GBK”);   
    // 实例化SmartUpload对象   
    SmartUpload su = new SmartUpload();   
    // 限制每个上传文件的最大长度   
    su.setMaxFileSize(10000);   
    // 限制总上传数据的长度   
    su.setTotalMaxFileSize(20000);   
    // 通过扩展名限制允许上传的文件   
    su.setAllowedFilesList("jpg,jpeg,gif,png");   
    // 通过扩展名限制禁止上传的文件   
    su.setDeniedFilesList("exe,bat,jsp,htm,html,txt");   
    // 将上传的文件保存到指定目录(项目的根目录WebRoot下的image中)   
    su.save("/image");   
    // 开始上传   
    su.upload();   
    // 取到每个上传文件   
    File file = su.getFiles().getFile(0);   
    // 获取上传文件的名称   
    String picName = file.getFileName();   
    // 设置上传文件存放在项目的根目录WebRoot下的image中   
    file.saveAs("/image/" + picName, su.SAVE_VIRTUAL);   
    %>  <%
    // 设置编码格式
    request.setCharacterEncoding(“GBK”);
    // 实例化SmartUpload对象
    SmartUpload su = new SmartUpload();
    // 限制每个上传文件的最大长度
    su.setMaxFileSize(10000);
    // 限制总上传数据的长度
    su.setTotalMaxFileSize(20000);
    // 通过扩展名限制允许上传的文件
    su.setAllowedFilesList("jpg,jpeg,gif,png");
    // 通过扩展名限制禁止上传的文件
    su.setDeniedFilesList("exe,bat,jsp,htm,html,txt");
    // 将上传的文件保存到指定目录(项目的根目录WebRoot下的image中)
    su.save("/image");
    // 开始上传
    su.upload();
    // 取到每个上传文件
    File file = su.getFiles().getFile(0);
    // 获取上传文件的名称
    String picName = file.getFileName();
    // 设置上传文件存放在项目的根目录WebRoot下的image中
    file.saveAs("/image/" + picName, su.SAVE_VIRTUAL);
    %>在获取表单元素时需要使用SmartUpload对象的getParameter()方法,而不是直接直接通过request获得,如下所示:Java代码 
    <%   
        String cmdNo = su.getRequest().getParameter("txtCmdNo"); // 商品编号   
        String cmdName = su.getRequest().getParameter("txtCmdName"); // 商品名称   
        String cmdType = su.getRequest().getParameter("txtType"); // 商品类型   
        String cmdModel = su.getRequest().getParameter("txtModel"); // 商品型号   
        String cmdBrand = su.getRequest().getParameter("txtBrand"); // 商品品牌   
        double cmdPrice = Double.parseDouble(su.getRequest().getParameter("txtCmdPrice")); // 商品价格   
        String cmdPic = picName; // 上传图片的文件名   
        String cmdDesc = su.getRequest().getParameter("txtDesc"); // 商品描述   
    %>  <%
        String cmdNo = su.getRequest().getParameter("txtCmdNo"); // 商品编号
        String cmdName = su.getRequest().getParameter("txtCmdName"); // 商品名称
        String cmdType = su.getRequest().getParameter("txtType"); // 商品类型
        String cmdModel = su.getRequest().getParameter("txtModel"); // 商品型号
        String cmdBrand = su.getRequest().getParameter("txtBrand"); // 商品品牌
        double cmdPrice = Double.parseDouble(su.getRequest().getParameter("txtCmdPrice")); // 商品价格
        String cmdPic = picName; // 上传图片的文件名
        String cmdDesc = su.getRequest().getParameter("txtDesc"); // 商品描述
    %> 一点拙见,Over!!!
      

  4.   

    还是用swfupload吧 做的确实不错了
      

  5.   

    隐藏表单的那个做法完全没有必要,
    给提交按钮注册个click事件
    然后在事件中调用提交方法,
    并返回false就行了,何必复制表单内容到
    隐藏表单,再用隐藏表单提交