用iframe模拟ajax上传文件
项目中同事使用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处理,原理都是一样的)package com.iflytek.demo; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * Servlet implementation class IframeAjax */ public class IframeAjax extends HttpServlet { private static final long serialVersionUID = 1L; /** * Default constructor. */ public IframeAjax() { // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 这里是取得WebContent的根目录路径 String realPath = request.getSession().getServletContext().getRealPath("/"); // 这里是为了方便管理上传的文件,因而在根目录下建立一个文件夹 File uploadPath = new File(realPath, "uploads"); uploadPath.mkdirs(); // 解决Servelt to js乱码问题 response.setContentType("text/html;charset=UTF-8"); // 判断是否是带有附件的上传 boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (isMultipart) { FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); ArrayList<String> pics = new ArrayList<String>(); try { @SuppressWarnings("unchecked") List<FileItem> items = upload.parseRequest(request); for (FileItem f : items) { if (f.isFormField()) {// 说明是表单项 } else {// 说明是文件 String srcName = f.getName();// 取得上传时的文件名 srcName = srcName.toLowerCase();// 统一将文件名改为小写 String extName = "";// 扩展名 int pos = srcName.lastIndexOf('.'); // 因为有的文件上传它可能没有扩展名,所以这里注意要进行一步判断,判断后再取得.扩展名 if (pos != -1) { extName = srcName.substring(pos); } // 取得当前时间的纳秒数加扩展名来做保存文件的文件名 String name = System.nanoTime() + extName; File file = new File(uploadPath, name); f.write(file);// 保存到指定的目录中去 pics.add(name); } } } catch (Exception e) { response.getWriter().write("<script>parent.callback(false,'图片上传失败','')</script>"); } response.getWriter().write("<script>parent.callback(true,'图片上传成功','" + pics.get(0) + "')</script>"); // 一般如果是直接表单提交的方法需要返回 // request.getRequestDispatcher("iframeAjax.jsp").forward(request, // response); } } }
小感:找找总会有方法的。
相关推荐
架构技术交流 2020-07-28
haohong 2020-07-18
tiankele0 2020-06-26
xiangxiaojun 2020-06-25
pythonclass 2020-06-04
WebVincent 2020-06-03
sixthelement 2020-05-30
云之高水之远 2020-05-19
云之高水之远 2020-05-17
Chydar 2020-05-15
tuxlcsdn 2020-04-17
ajaxtony 2020-02-03
STPace 2020-02-03
学留痕 2013-05-11
云之高水之远 2020-01-05
TONIYH 2019-12-20
nimeijian 2019-12-15
我只是个程序员 2014-01-18