用iframe模拟ajax上传文件

Posted on 2014-01-02 09:25  小桥流水人家,美。  阅读(323)  评论(0)    收藏  举报

项目中同事使用AjaxFrom上传文件时后台保存成功,而前台却不进回调函数。自己也没去解决掉这个问题,后来同事介绍说用iframe模拟Ajax,自己从网上也看到了一些iframe做伪Ajax上传的,感觉也算是一个小技巧,故而在此记录一下。

网上说,直接用$.post在上传文本信息没有问题,但是直接上传图片就不行了。当然其实这个我们也可以使用封装好的flash方法,但是封装好的东西灵活性差,而且也不见得都会对flash进行修改。所以iframe模拟就是一个比较不错的选择。

iframeAjax.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">  
  • <meta http-equiv="pragma" content="no-cache">  
  • <meta http-equiv="cache-control" content="no-cache">  
  • <meta http-equiv="expires" content="0">  
  • <script type="text/javascript" src="./res/js/jquery-1.8.2.js">  
  •        
  • </script>  
  • <title>Iframe 模拟AJax提交</title>  
  • <script type="text/javascript">  
  •     function uploadImg() {   
  •         var names = $("#imageId").val().split(".");   
  •         if (names[1] != "gif" && names[1] != "GIF" && names[1] != "jpg"   
  •                 && names[1] != "JPG" && names[1] != "png" && names[1] != "PNG") {   
  •             $("#errorTip").html("海报必须为gif,jpg,png格式");   
  •             $("#errorTip").show();   
  •             return;   
  •         }   
  •         $("#formId").submit();   
  •     }   
  •   
  •     function callback(success, message, url) {   
  •         if (success == false) {   
  •             $("#errorTip").html(message);   
  •             $("#errorTip").show();   
  •         } else {   
  •             $("#errorTip").hide();   
  •             $("#successTip").html(message);   
  •             $("#successTip").show();   
  •             $("#img").attr("src", "uploads/" + url);   
  •             $("#img").show();   
  •         }   
  •     }   
  • </script>  
  • </head>  
  • <body>  
  •   
  •     <form id="formId" action="IframeAjax" method="post"  
  •         target="hiddenFrameName" enctype="multipart/form-data">  
  •         <div>  
  •             <label>附件:</label> <input id="imageId" type="file" name="imageName"  
  •                 onchange="uploadImg()" />  
  •             <div style="display: none; color: red;" id="errorTip">活动海报不可为空   
  •             </div>  
  •             <div style="display: none; color: green;" id="successTip"></div>  
  •         </div>  
  •     </form>  
  •     <iframe style="display: none" name='hiddenFrameName' id="hidden_frame"></iframe>  
  •   
  •     <img id="img" src="" width="80" height="80" style="display: none;" />  
  •   
  •   
  • </body>  
  • </html>

说明:
  form表单中action正常填写处理文件上传的操作。target填写一个隐藏的iframe的name。这样表单提交之后,文件会被上传,但是页面却不会刷新,因为表单提交后被刷新页面为隐藏的iframe,因此用户看到的效果和ajax处理的效果是一样的。
同时我们知道Ajax另一个就是回调处理,那么我们这里也可以定义几个需要回调处理的JS方法,然后在后台调用。

IframeAjax.java(这里我直接采用的Servlet处理,原理都是一样的)

  1. package com.iflytek.demo;   
  2.   
  3. import java.io.File;   
  4. import java.io.IOException;   
  5. import java.util.ArrayList;   
  6. import java.util.List;   
  7.   
  8. import javax.servlet.ServletException;   
  9. import javax.servlet.http.HttpServlet;   
  10. import javax.servlet.http.HttpServletRequest;   
  11. import javax.servlet.http.HttpServletResponse;   
  12.   
  13. import org.apache.commons.fileupload.FileItem;   
  14. import org.apache.commons.fileupload.FileItemFactory;   
  15. import org.apache.commons.fileupload.disk.DiskFileItemFactory;   
  16. import org.apache.commons.fileupload.servlet.ServletFileUpload;   
  17.   
  18. /**  
  19.  * Servlet implementation class IframeAjax  
  20.  */  
  21. public class IframeAjax extends HttpServlet {   
  22.     private static final long serialVersionUID = 1L;   
  23.   
  24.     /**  
  25.      * Default constructor.  
  26.      */  
  27.     public IframeAjax() {   
  28.         // TODO Auto-generated constructor stub   
  29.     }   
  30.   
  31.     /**  
  32.      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse  
  33.      *      response)  
  34.      */  
  35.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {   
  36.         // TODO Auto-generated method stub   
  37.     }   
  38.   
  39.     /**  
  40.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse  
  41.      *      response)  
  42.      */  
  43.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {   
  44.         // 这里是取得WebContent的根目录路径   
  45.         String realPath = request.getSession().getServletContext().getRealPath("/");   
  46.         // 这里是为了方便管理上传的文件,因而在根目录下建立一个文件夹   
  47.         File uploadPath = new File(realPath, "uploads");   
  48.         uploadPath.mkdirs();   
  49.         // 解决Servelt to js乱码问题   
  50.         response.setContentType("text/html;charset=UTF-8");   
  51.         // 判断是否是带有附件的上传   
  52.         boolean isMultipart = ServletFileUpload.isMultipartContent(request);   
  53.         if (isMultipart) {   
  54.             FileItemFactory factory = new DiskFileItemFactory();   
  55.             ServletFileUpload upload = new ServletFileUpload(factory);   
  56.             ArrayList<String> pics = new ArrayList<String>();   
  57.             try {   
  58.                 @SuppressWarnings("unchecked")   
  59.                 List<FileItem> items = upload.parseRequest(request);   
  60.                 for (FileItem f : items) {   
  61.                     if (f.isFormField()) {// 说明是表单项   
  62.                     } else {// 说明是文件   
  63.                         String srcName = f.getName();// 取得上传时的文件名   
  64.                         srcName = srcName.toLowerCase();// 统一将文件名改为小写   
  65.                         String extName = "";// 扩展名   
  66.                         int pos = srcName.lastIndexOf('.');   
  67.                         // 因为有的文件上传它可能没有扩展名,所以这里注意要进行一步判断,判断后再取得.扩展名   
  68.                         if (pos != -1) {   
  69.                             extName = srcName.substring(pos);   
  70.                         }   
  71.                         // 取得当前时间的纳秒数加扩展名来做保存文件的文件名   
  72.                         String name = System.nanoTime() + extName;   
  73.                         File file = new File(uploadPath, name);   
  74.                         f.write(file);// 保存到指定的目录中去   
  75.                         pics.add(name);   
  76.   
  77.                     }   
  78.                 }   
  79.             } catch (Exception e) {   
  80.                 response.getWriter().write("<script>parent.callback(false,'图片上传失败','')</script>");   
  81.             }   
  82.   
  83.             response.getWriter().write("<script>parent.callback(true,'图片上传成功','" + pics.get(0) + "')</script>");   
  84.             // 一般如果是直接表单提交的方法需要返回   
  85.             // request.getRequestDispatcher("iframeAjax.jsp").forward(request,   
  86.             // response);   
  87.   
  88.         }   
  89.     }   
  90.   
  91. }  

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3