模拟异步方式上传文件

来源:互联网 发布:pid控制算法和图解 编辑:程序博客网 时间:2024/05/17 18:13

        外包项目已经部分上线,突然甲方测试出上传文件有问题,IE10及以下版本、火狐低版本、其它浏览器的一些版本等上传都失败。

        当项目主管跟我提出这个问题时,我们看了下,整个项目有约30多处涉及到了文件上传(包括图片和非图片),每一处上传涉及到界面元素、后端处理、js回调处理,其中js部分是一个共同的方法(也有特殊要求而重写的其它类似方法),界面上,在单击图片空白框后,弹出浏览文件的界面供用户选择要上传的文件,确定后,图片及时显示出来,待真正提交表单后,将图片的路径信息保存在库中,被上传的文件保存在项目外的文件夹下,显示时复制到项目内。之所以上传失败,是因为js的上传方法使用了FormData对象,这个对象只在支持html5的高版本浏览器中才可以使用。现在问题是,如果要改,涉及的面比较大,最关键的是,如何改?因为甲方很强势,界面必需满足原型设计。当初之所以这样上传,完全是为了项目进度,直接采用了上一个项目的上传方案。现在出现兼容问题,弄不好要拖累项目的进度。

        不管是上传图片还是pdf等文档,在上传后,要能马上看图片或pdf的缩略图,这里涉及到一个异步上传问题。

        如果不使用FormData对象,可能就不能及时显示图片,虽然jquery的post使用$('#form').serialize()可以异步提交表单,但对于file的input域,根本不起作用。网上搜索异步上传文件的方法,倒是有不少方案,有jquery.form.js的、有用其它方式,但试了其中的方式后,发现很多方案最后用的还是FormData。

        如果将上传input域单独使用一个form,可以上传,但页面跳走,其它信息不能提交。能不能提交后不跳走,并能返回 后台信息呢?即做到异步提交又能回调呢?

        在反复调找后,总算找到一种方式,可以模拟异步上传,又能返回信息。如果按此法改造各个上传的地方,应该是容易的,不是那种推到式的重写。最大特点是,它采用了普通方式上传文件,就不存在浏览器兼容问题了。

       现摘取其中部分代码,以作记载。

      前端部分, 两个jsp页面,一个主页,用于放整个表单信息,一个专门放上传域。

<script type="text/javascript">
    function callBack(data){//后台上传完成后回调,参数为文件的路径信息
         var json=eval('('+data+')');
          $('#aImage').attr('src','/echarts'+json['fileURL']);//将图片显示在界面上
          $('#path').val(json['fileURL']);//保存文件的路径信息用于表单提交
    }
</script>
</head>
<body>
   <form action="/echarts/up/submitForm" method="post">
    <input type="text"  name="title"  id="title" value="输入标题"/>
    <input type="hidden"  name="path"  id="path" value="隐藏的待提交的已经上传的文件地址"/>
    <img id="aImage" src="" onclick="javascript:iframe.window.$('#afile').click()" width="100" height="100">
    <input type="submit" value="提交">
    </form>
    <iframe src="/echarts/upload/do.jsp" id="iframe" name="iframe" style="display: none;"></iframe>
</body>

上传域jsp(名称do.jsp,放入上面隐藏的iframe中):

<script type="text/javascript">
    function subform(){
       $('#fileform').submit();//提交表单
    }
</script>
<form action="/echarts/up/uploadAttachment" id="fileform" enctype="multipart/form-data" method="post" style="display: none;">
      <input type="file"  name="afile" id="afile" onchange="subform()"/>
</form>

后台部分:

public String uploadAttachment(){
        try{
            HttpServletResponse response = ServletActionContext.getResponse();
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out= response.getWriter();
            String path=ServletActionContext.getRequest().getRealPath("/uploadfile");
            String fileURL=path+"/"+afileFileName;
            
            FileUtils.copyFile(afile,new File(fileURL));
            String res="{success:'true',fileURL:'/uploadfile/"+afileFileName+"'}";
            String rt="<script>window.parent.callBack(\""+res+"\");</script>";//就靠这句回调前端
            out.print(rt);
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }


因为不是真正的异步,所以如果上传的文件较大,可能会有一个不应期,这个应该正好,因为只有传完后才能到下一步。以前的方式倒是有问题了,还没有等上传完成就可提交表单,路径信息可能丢失。

0 0
原创粉丝点击