当前位置: 代码迷 >> Ajax >> 类似ajax文件下传功能 其一(只针对同一个页面只有一个下传功能)
  详细解决方案

类似ajax文件下传功能 其一(只针对同一个页面只有一个下传功能)

热度:222   发布时间:2012-11-23 00:03:43.0
类似ajax文件上传功能 其一(只针对同一个页面只有一个上传功能)

写了一个简单的类似ajax上传文件的功能,原理当然不是真正的通过ajax方式上传,而是利用iframe来做的

这是其中的一种写法:

先来分析一下原理,利用js来创建一个iframe,这个iframe的src指向一个静态页面。这个静态页面当中有一个Form表单

进行提交。后台提交成功后让其运行一个父窗口的js函数,并返回上传成功的文件路径、

?

先来看js,由于有一些参数是可变的,所以代码上有些混杂.(程序当中为方便,用到了jquery框架)

?

var Upload = {};
Upload = {
    formId:"D_upload_form",
    imgURL : "http://www.xxxx.com:8080/img",
    action : "/img/upload.htm",
    currentFilePath:null,
    allFilePath:new Array(),
    imgPreDiv:null,
    uploadInfo:null,
    checkType:2,//默认检测类型为图片格式
    imgTemplate:null,   //图片显示模板格式
    maxNum:5,   //最大上传数量
    hasUploadNum:0,//已经上传的数量
    /**
     * 如果需要修改默认参数调用此方法.
     */
    setting:function(uploadURL, upladAction, checkType) {
        Upload.imgURL = uploadURL || Upload.imgURL;
        Upload.action = upladAction || Upload.action;
        Upload.checkType = checkType || Upload.checkType;
    },
    /**
     * 创建文件上传
     * @param fileID 当前file控件ID
     * @param imgListDivId 如果是图片,则可设置图片上传完成后显示的缩略图的位置
     * @param infoId 提示用户正在上传的信息所在的标签ID
     * @param imgTemplate 图片上传后显示的的格式模板,程序根据此模板自动生成后续的图片样式
     */
    createUpload:function(fileID, imgListDivId, infoId, imgTemplate) {
        if (typeof($) != "function") {
            alert("请导入jquery1.2.6以上版本JS文件");
            return;
        }
        var fileInput = $("#" + fileID);
        var iframeWidth = fileInput.parent().css("width") || "250";
        var iframeHeight = fileInput.parent().css("height") || "30";
        var html = "<iframe frameborder='0' id='D_upload_iframe' scrolling='no' src='" + Upload.imgURL
                + "/html/upload.html' width='" + iframeWidth + "' height='" + iframeHeight + "'></iframe>";
        fileInput.parent().html(html);
        if (imgListDivId != null || imgListDivId != "") {
            Upload.imgPreDiv = $("#" + imgListDivId);
        }
        if (infoId != null || infoId != "") {
            Upload.uploadInfo = $("#" + infoId);
        }
        if (imgTemplate != null || imgTemplate != "") {
            Upload.imgTemplate = $("#" + imgTemplate).html();
        }

    },
    /**
     * 供后台程序调用,设置当前上传成功的文件路径
     * @param path 上传后的路径
     */
    setFilePath:function(path) {
        Upload.currentFilePath = path;
        Upload.allFilePath.push(path);
        //var img = "<img src='" + path + "' alt='上传的图片,可删除'/>";
        var img = Upload.imgTemplate.replace("src=\"\"", "src=\"" + path + "\"");
        if (Upload.imgPreDiv != null) {
            Upload.imgPreDiv.append(img);
        }
        history.back();
        Upload.uploadInfo.hide();
    },
    /**
     * 供后台程序调用,当上传出现错误时弹出错误提示框
     * @param error 错误信息
     */
    uploadError:function(error) {
        alert(error);
        history.back();
        Upload.uploadInfo.hide();
    },
    /**
     * 获取当前上传的文件路径
     */
    getFilePath:function() {
        return Upload.currentFilePath;
    },
    /**
     * 显示正在上传信息
     */
    showUploadInfo:function() {
        Upload.uploadInfo.show();
    }
};

上面的JS?方法基本没什么可说的,通过获取当前页面当中的一个input对象,将其替换成一个iframe并保留一些参数

?

?

下面来看iframe静态页面内容:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title></title>
    <meta http-equiv="Content-type" content="text/html;chartset=utf-8"/>

</head>
<body style="padding:0;">
<form style="padding:0;" method="post" action="" enctype="multipart/form-data">
    <input type="file" name="fileName" onchange="listernInputChange(this,this.form);"/>
</form>
</body>
<script type="text/javascript">
        function iframeLoad() {
        if (parent.Upload == null || parent.Upload == "undefined") {
            alert("您的设置可能问题,或访问了不该的页面!");
            history.back();
        } else {
            document.forms[0].action = parent.Upload.imgURL + parent.Upload.action;
        }
    }
    function listernInputChange(input, form) {
        var form1 = form || document.forms[0];
        var pattern = /\.(jpg|jpeg|gif|bmp|png)(\s|$)/i;
        if (parent.Upload.checkType == 1) {
            pattern = /\.(css)(\s|$)/i;
        } else if (parent.Upload.checkType == 3) {
            pattern = /\.(swf)(\s|$)/i;
        }
        var url = input.value;
        if (parent.Upload.hasUploadNum < parent.Upload.maxNum) {
            if (!pattern.test(url)) {
                alert("上传的文件格式不正确");
            } else {
                parent.Upload.showUploadInfo();
                form1.submit();
            }
            parent.Upload.hasUploadNum++;
        } else {
            alert("已达到最大上传数量,不可以再上传");
        }
    }
    iframeLoad();
</script>
</html>

iframe页面当中,做了如下事:

1:获取父窗口当中传入的action路径

2:获取用户设置的最大上传数量及上传的文件类型

3:监听浏览按钮的change事件进行表单提交

整个页面调用了父窗口当中的JS函数来获取相关的参数

?

现在来看后台代码:

 protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String imgPath = "";
        String sectionPath = "";
        String fileName = "";
        StringBuffer uploadError = null;
        try {
            response.setContentType("text/html;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();
            //获取当前项目所在的绝对路径
            if (DStringUtil.isEmpty(UploadCtrl.CONTEXT_PATH)) {
                UploadCtrl.CONTEXT_PATH = request.getSession().getServletContext().getRealPath("/");
            }
            //文件保存路径
            String path = request.getParameter("savePath");
            //检测类型
            String checkType = request.getParameter("checkType");
            //默认检测的文件类型为图片格式,可以设置指定类型
            byte cType = UploadUtil.IMG_TYPE;
            if (DStringUtil.isEmpty(path)) {
                path = ConfigUtil.DEFAULT_IMG_PATH;
            }
            if ((!DStringUtil.isEmpty(checkType)) && DStringUtil.isNumber(checkType)) {
                cType = Byte.valueOf(checkType);
            }
            sectionPath = UploadCtrl.CONTEXT_PATH + path;
            uploadError = new StringBuffer(); //保存上传当中的错误信息,有错误时,不回滚
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile file = multipartRequest.getFile("fileName");
            if (file.getSize() > 0) {
                String error = UploadUtil.checkFileExt_SIZE(file, cType, ConfigUtil.MAX_IMG_50K);
                if (DStringUtil.isEmpty(error)) {
                    imgPath = UploadUtil.uploadTempFile(sectionPath, file, CreateCode.getCode());
                    fileName = imgPath;
                    imgPath = imgURL + path + "/" + imgPath;
                }
                uploadError.append(error);
            }
            if (uploadError.length() == 0) {
                //插入图片
                out.println("<html>");
                out.println("<head>");
                out.println("<title>Insert Image</title>");
                out.println("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">");
                out.println("</head>");
                out.println("<body>");
                out.println("<script type=\"text/javascript\">parent.Upload.setFilePath(\"" + imgPath + "\")</script>");
                out.println("</body>");
                out.println("</html>");
            } else {
                out.println("<html>");
                out.println("<head>");
                out.println("<title>error</title>");
                out.println("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">");
                out.println("</head>");
                out.println("<body>");
                out.println("<script type=\"text/javascript\">parent.Upload.uploadError(\"" + uploadError.toString() + "\");</script>");
                out.println("</body>");
                out.println("</html>");
            }
        } catch (Exception e) {
            logger.error("上传图片:" + e);
            if (!DStringUtil.isEmpty(imgPath)) {
                UploadUtil.deleteFile(sectionPath + "/" + fileName);
            }
            throw e;
        } finally {
            if (uploadError != null && !DStringUtil.isEmpty(uploadError.toString())) {
                UploadUtil.deleteFile(sectionPath + "/" + fileName);
            }
        }
        return null;
    }

?

以上代码当中用了一些工具类,在这里并未给出,重点的是看后面上传成功后如果让其将路径返回给父窗口

查看其中的红色代码,这里利用response写入一段代码,并让其运行父窗口当中的方法,通过传参的方式,将文件路径告之父窗口。

?

来看演示HTML:

    <script type="text/javascript">
        $(function() {
            //创建上传文件,及处理上传成功后的操作
            Upload.createUpload("imgFile", "imgList", "D_upload_label_info", "ImageTemplate");
          //Upload.createUpload("imgFile2", "imgList2", "", "");

        });
    </script>


<%--图片显示模板格式--%>
<div id="ImageTemplate">
    <div>
        <img src="" alt="图片位置"/></div>
</div>
<%--图片显示位置--%>
<div id="imgList" style="height:150px;">

</div>
<div style="height:30px;">
    <%--只是一个占位符--%>
    <input id="imgFile" type="file" name="imgFile"/>
</div>
<div>
    <label id="D_upload_label_info" style="display:none;">正在上传....</label>
</div>

<div>
    <input id="imgFile2" type="file" name="imgFile"/>
</div>
<%--图片显示位置--%>
<div id="imgList2" style="height:150px;">
  </div>

?

?

?

以上就是整个上传的过程。

不足之处:目前在同一个页面只能有一个上传的文件选择框,不能有多个不同提交路径及不同参数的上传框。

?

?

?

  相关解决方案