zoukankan      html  css  js  c++  java
  • ajax异步文件上传,iframe方式

    不是我写的,我看了他的,思路很明确:

    实现思路:

    在js脚本中动态创建form,动态创建form中的内容,将文件上传的内容以隐藏域的方式提交过去,然后写好回调等。

    感觉思路不难,但是我写不出来,感觉需要对于url,http有一定了解,js也ok才可。

    代码:

    上传的js:

    // JavaScript Document
    jQuery.extend({
    
        createUploadIframe: function(id, uri)
     {
       //create frame
                var frameId = 'jUploadFrame' + id;
                
                if(window.ActiveXObject) {
                    //var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
                    if(jQuery.browser.version=="9.0" || jQuery.browser.version=="10.0"){  
                        var io = document.createElement('iframe');  
                        io.id = frameId;  
                        io.name = frameId;  
                    }else if(jQuery.browser.version=="6.0" || jQuery.browser.version=="7.0" || jQuery.browser.version=="8.0"){  
                        var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');  
                        if(typeof uri== 'boolean'){
                            io.src = 'javascript:false';
                        }
                        else if(typeof uri== 'string'){
                            io.src = uri;
                        }
                    }
                }else {
                    var io = document.createElement('iframe');
                    io.id = frameId;
                    io.name = frameId;
                }
                io.style.position = 'absolute';
                io.style.top = '-1000px';
                io.style.left = '-1000px';
    
                document.body.appendChild(io);
    
                return io;   
        },
        createUploadForm: function(id, fileElementId, data)
     {
      //create form 
      var formId = 'jUploadForm' + id;
      var fileId = 'jUploadFile' + id;
      var form = jQuery('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>'); 
      var oldElement = jQuery('#' + fileElementId);
      var newElement = jQuery(oldElement).clone();
      jQuery(oldElement).attr('id', fileId);
      jQuery(oldElement).before(newElement);
      jQuery(oldElement).appendTo(form);
      
      //add data
      if(data) { 
        for (var i in data) { 
            $('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form); 
        } 
      }
      //set attributes
      jQuery(form).css('position', 'absolute');
      jQuery(form).css('top', '-1200px');
      jQuery(form).css('left', '-1200px');
      jQuery(form).appendTo('body');  
      return form;
        },
    
        ajaxFileUpload: function(s) {
            // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout  
            s = jQuery.extend({}, jQuery.ajaxSettings, s);
            var id = s.id;        
            //var id = s.fileElementId;        
            var form = jQuery.createUploadForm(id, s.fileElementId,s.data);
            var io = jQuery.createUploadIframe(id, s.secureuri);
            var frameId = 'jUploadFrame' + id;
            var formId = 'jUploadForm' + id;  
            
            if( s.global && ! jQuery.active++ ){
                // Watch for a new set of requests
                jQuery.event.trigger( "ajaxStart" );
            }            
            var requestDone = false;
            // Create the request object
            var xml = {};   
            if( s.global ){
             jQuery.event.trigger("ajaxSend", [xml, s]);
            }            
            
            var uploadCallback = function(isTimeout){  
                // Wait for a response to come back 
                var io = document.getElementById(frameId);
                try{    
                    if(io.contentWindow){
                        xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
                        xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
                    }else if(io.contentDocument){
                        xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
                        xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
                    }      
                }catch(e){
                    jQuery.handleError(s, xml, null, e);
                }
                if( xml || isTimeout == "timeout"){    
                    requestDone = true;
                    var status;
                    try {
                        status = isTimeout != "timeout" ? "success" : "error";
                        // Make sure that the request was successful or notmodified
                        if( status != "error" ){
                            // process the data (runs the xml through httpData regardless of callback)
                            var data = jQuery.uploadHttpData( xml, s.dataType );                        
                            if( s.success ){
                                // ifa local callback was specified, fire it and pass it the data
                                s.success( data, status );
                            };                 
                            if( s.global ){
                                // Fire the global callback
                                jQuery.event.trigger( "ajaxSuccess", [xml, s] );
                            };                            
                        } else{
                         jQuery.handleError(s, xml, status);
                        }
                            
                    } catch(e){
                        status = "error";
                        jQuery.handleError(s, xml, status, e);
                    };                
                    if( s.global ){
                        // The request was completed
                        jQuery.event.trigger( "ajaxComplete", [xml, s] );
                    };
    
                    // Handle the global AJAX counter
                    if(s.global && ! --jQuery.active){
                     jQuery.event.trigger("ajaxStop");
                    };
                    if(s.complete){
                      s.complete(xml, status);
                    };                 
    
                    jQuery(io).unbind();
                    setTimeout(function(){
                    try{
                        jQuery(io).remove();
                        jQuery(form).remove(); 
                    }catch(e){
                          jQuery.handleError(s, xml, null, e);
                    }}, 100);
                    xml = null;
                };
            }
            // Timeout checker
            if( s.timeout > 0 ){
                setTimeout(function(){if(!requestDone ){uploadCallback( "timeout" );}}, s.timeout);
            }
            try{
                var form = jQuery('#' + formId);
                jQuery(form).attr('action', s.url);
                jQuery(form).attr('method', 'POST');
                jQuery(form).attr('target', frameId);
                if(form.encoding){
                    form.encoding = 'multipart/form-data';    
                }else{    
                    form.enctype = 'multipart/form-data';
                }   
                jQuery(form).submit();
    
            } catch(e){   
                jQuery.handleError(s, xml, null, e);
            }
            /*if(window.attachEvent){
                document.getElementById(frameId).attachEvent('onload', uploadCallback);
            }
            else{
                document.getElementById(frameId).addEventListener('load', uploadCallback, false);
            }   */
            jQuery('#' + frameId).load(uploadCallback);
            return {abort: function () {}}; 
    
        },
    
        uploadHttpData: function( r, type ) {
            var data = !type;
            data = type == "xml" || data ? r.responseXML : r.responseText;
            // ifthe type is "script", eval it in global context
            if( type == "script" ){
             jQuery.globalEval( data );
            }
                
            // Get the JavaScript object, ifJSON is used.
            if( type == "json" ){
                data = r.responseText;  
                var start = data.indexOf(">");  
                if(start != -1) {  
                  var end = data.indexOf("<", start + 1);  
                  if(end != -1) {  
                    data = data.substring(start + 1, end);  
                   }  
                }  
                eval( "data = " + data);  
            }
                
            // evaluate scripts within html
            if( type == "html" ){
             jQuery("<div>").html(data).evalScripts();
            }
                
            return data;
        },
        /*handleError: function( s, xml, status, e ) {
            // If a local callback was specified, fire it
            if ( s.error )
                s.error( xml, status, e );
    
            // Fire the global callback
            if ( s.global )
                jQuery.event.trigger( "ajaxError", [xml, s, e] );
        }*/
        handleError: function( s, xhr, status, e ) {
            // If a local callback was specified, fire it
            if ( s.error ) {
                s.error.call( s.context || s, xhr, status, e );
            }
            // Fire the global callback
            if ( s.global ) {
                (s.context ? jQuery(s.context) : jQuery.event).trigger("ajaxError", [xhr, s, e] );
            }
        }
    });
    View Code

    前台页面:

    <%@ 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">
    <title>Ajax File Uploader Plugin For Jquery</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="ajaxfileupload.js"></script>
    <script type="text/javascript">
        function ajaxFileUpload() {
            $.ajaxFileUpload({
                url : 'upload',
                secureuri : false,
                fileElementId : 'fileToUpload',
                dataType : 'json',
                data : {username : $("#username").val()},
                success : function(data, status) {
                    $('#viewImg').attr('src',data.picUrl);
                },
                error : function(data, status, e) {
                    alert('上传出错');
                }
            })
    
            return false;
    
        }
    </script>
    </head>
    
    <body>
        <h1>选择图片后,点击按钮上传</h1>
        <input id="fileToUpload" type="file" size="45" name="fileToUpload"
            class="input">
        <button class="button" onclick="ajaxFileUpload()">上传</button>
        <br>
        <img id="viewImg">
    </body>
    </html>
    View Code

    后台servlet:

    package upload;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Date;
    import java.util.List;
    
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletContext;
    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.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    /**
     * 
     * 文件上传 具体步骤: 1)获得磁盘文件条目工厂 DiskFileItemFactory 要导包 2) 利用 request 获取 真实路径
     * ,供临时文件存储,和 最终文件存储 ,这两个存储位置可不同,也可相同 3)对 DiskFileItemFactory 对象设置一些 属性
     * 4)高水平的API文件上传处理 ServletFileUpload upload = new ServletFileUpload(factory);
     * 目的是调用 parseRequest(request)方法 获得 FileItem 集合list ,
     * 
     * 5)在 FileItem 对象中 获取信息, 遍历, 判断 表单提交过来的信息 是否是 普通文本信息 另做处理 6) 第一种. 用第三方 提供的
     * item.write( new File(path,filename) ); 直接写到磁盘上 第二种. 手动处理
     * 
     */
    public class UploadProcessorServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
        // 保存文件的目录
        private static String PATH_FOLDER = "/";
        // 存放临时文件的目录
        private static String TEMP_FOLDER = "/";
        
        
        @Override
        public void init(ServletConfig config) throws ServletException {
            ServletContext servletCtx = config.getServletContext();
            // 初始化路径
            // 保存文件的目录
            PATH_FOLDER = servletCtx.getRealPath("/upload");
            // 存放临时文件的目录,存放xxx.tmp文件的目录
            TEMP_FOLDER = servletCtx.getRealPath("/uploadTemp");
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
         *      response)
         */
        protected void doGet(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8"); // 设置编码
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=UTF-8");
            // 获得磁盘文件条目工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            
            // 如果没以下两行设置的话,上传大的 文件 会占用 很多内存,
            // 设置暂时存放的 存储室 , 这个存储室,可以和 最终存储文件 的目录不同
            /**
             * 原理 它是先存到 暂时存储室,然后在真正写到 对应目录的硬盘上, 按理来说 当上传一个文件时,其实是上传了两份,第一个是以 .tem
             * 格式的 然后再将其真正写到 对应目录的硬盘上
             */
            factory.setRepository(new File(TEMP_FOLDER));
            // 设置 缓存的大小,当上传文件的容量超过该缓存时,直接放到 暂时存储室
            factory.setSizeThreshold(1024 * 1024);
    
            // 高水平的API文件上传处理
            ServletFileUpload upload = new ServletFileUpload(factory);
            
            try {
                // 提交上来的信息都在这个list里面
                // 这意味着可以上传多个文件
                // 请自行组织代码
                List<FileItem> list = upload.parseRequest(request);
                // 获取上传的文件
                FileItem item = getUploadFileItem(list);
                // 获取文件名
                String filename = getUploadFileName(item);
                // 保存后的文件名
                String saveName = new Date().getTime() + filename.substring(filename.lastIndexOf("."));
                // 保存后图片的浏览器访问路径
                String picUrl = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/upload/"+saveName;
    
                System.out.println("存放目录:" + PATH_FOLDER);
                System.out.println("文件名:" + filename);
                System.out.println("浏览器访问路径:" + picUrl);
    
                // 真正写到磁盘上
                item.write(new File(PATH_FOLDER, saveName)); // 第三方提供的
                
                PrintWriter writer = response.getWriter();
                
                writer.print("{");
                writer.print("msg:"文件大小:"+item.getSize()+",文件名:"+filename+""");
                writer.print(",picUrl:"" + picUrl + """);
                writer.print("}");
                
                writer.close();
            
            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
        
        private FileItem getUploadFileItem(List<FileItem> list) {
            for (FileItem fileItem : list) {
                if(!fileItem.isFormField()) {
                    return fileItem;
                }
            }
            return null;
        }
        
        private String getUploadFileName(FileItem item) {
            // 获取路径名
            String value = item.getName();
            // 索引到最后一个反斜杠
            int start = value.lastIndexOf("/");
            // 截取 上传文件的 字符串名字,加1是 去掉反斜杠,
            String filename = value.substring(start + 1);
            
            return filename;
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
         *      response)
         */
        protected void doPost(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    
    }
    View Code

    文章来自:http://blog.csdn.net/thc1987/article/details/15341201

  • 相关阅读:
    0719PHP基础:PDO
    0717PHP基础:面向对象
    0716PHP基础:面向对象
    0715JS基础:ajax
    0715PHP练习:文件操作
    0715PHP基础:文件操作
    0629正则表达式:基础
    0628正则表达式:练习
    zTree简单使用和代码结构
    servlet
  • 原文地址:https://www.cnblogs.com/aigeileshei/p/6082929.html
Copyright © 2011-2022 走看看