zoukankan      html  css  js  c++  java
  • 文件上传前检测客户端文件大小的三种方法

    前段时间,因工作需要,需要在文件上传时限制文件的大小,所以需要在上传之前检测文件的大小。

    方法一:js检测文件大小

    一开始的想法是通过js直接在前端检测文件大小,代码如下:

    //获取上传文件大小
    function getFileSize(filePath)
    {
        var vBrowserVersion = getBrowserVersion();
        if("MSIE6.0" == vBrowserVersion){//对于IE6,使用Image的fileSize属性进行判断文件大小
               var image=new Image();
               image.dynsrc=filePath;
              return image.fileSize;
        }else if(vBrowserVersion.indexOf("MSIE")>=0){//对于IE6以上浏览器(IE6是公司默认最低版本),使用ActiveXObject进行上传
            var fso = new ActiveXObject("Scripting.FileSystemObject");
            return fso.GetFile(filePath).size;
        }else{//其它的浏览器,也是采用Image的fileSize属性进行判断文件大小
               var image=new Image();
               image.dynsrc = filePath;
              return image.fileSize;
        }
    }

    但这种方法存在一些弊端:

    1、IE6下面是利用的Image标签的dynsrc属性去判断;

    2、IE8下面使用ActiveXObject进行上传的话,是IE安全机制不支持的,需要降低本地浏览器的安全设置,对于开发者来说,是不可能去限制用户的。

    故这种方法不可行。

    方法二:java读取文件流方式

    接着的一种做法是通过dwr的方式,将文件路径传到后台去,再去读取文件的大小。代码如下:

     1 /**
     2      * 读取单据所带的附件总大小
     3      * 
     4      * @param filaPath 准备上传的文件的路径
     5      * @param moduleKey 文件对象类型
     6      * @param moduleObjectId 文件对象ID
     7      * @return lAttachmentTotalSize 该单据的附件总大小
     8      * @throws AttachmentException
     9      */
    10     public static long getAttachmentTotalSize(String filePath, String moduleKey, String moduleObjectId)
    11         throws AttachmentException {
    12         // 附件总大小
    13         long lAttachmentTotalSize = 0;
    14         // 准备上传的文件大小
    15         long lAttachmentSize = 0;
    16         // 已经保存的附件的大小
    17         long lExistAttachmentSize = 0;
    18         FileInputStream fis = null;
    19         // 根据对象类型和对象ID查询出已经保存的附件
    20         List lstAttachment = queryAttachmentList(moduleKey, moduleObjectId);
    21         if (null != lstAttachment && lstAttachment.size() > 0) {
    22             for (int i = 0, iSize = lstAttachment.size(); i < iSize; i++) {
    23                 AttachmentVO vo = (AttachmentVO) lstAttachment.get(i);
    24                 // 读取附件的大小,并累加
    25                 lExistAttachmentSize += vo.getFileSize();
    26             }
    27         }
    28         // 根据filePath读取准备上传的文件大小,与已经保存的文件大小相加
    29         try {
    30             File ff = new File(filePath);
    31             if (ff.exists()) {
    32                 fis = new FileInputStream(ff);
    33                 lAttachmentSize = fis.available();
    34             } else {
    35                 logger.error("AttachmentUtil.getAttachmentTotalSize方法,获取准备上传的文件时,文件不存在");
    36             }
    37         } catch (IOException ex) {
    38             logger.error("AttachmentUtil.getAttachmentTotalSize方法,读取文件大小时发生异常", ex);
    39         } finally {
    40             // 关闭流
    41             try {
    42                 if (null != fis) {
    43                     fis.close();
    44                 }
    45             } catch (IOException ex) {
    46                 logger.error("关闭流时发生异常", ex);
    47             }
    48         }
    49         // 附件总大小=已经存在的附件大小+准备上传的附件大小
    50         lAttachmentTotalSize = lExistAttachmentSize + lAttachmentSize;
    51         return lAttachmentTotalSize;
    52     }

    这个方法也存在一些弊端:

    1、服务器端在读取文件路径时,是访问不了客户端的文件的,它只会放在服务器端自己对应路径下的文件,但往往这个路径下是不存在对应文件的,故读取出来的文件大小总为0;

    2、IE8下由于安全问题,服务端获取客户端文件的路径,会变为C:/fakePath问题,这个问题在下一篇文章中会有解决方案;

    方法三:Ajax异步提交表单获取文件大小

    最后采取的一种方法是,通过Ajax进行异步的表单提交,因为form里面使用了file标签,是可以拿到文件的大小的。代码如下:

     1 //定义ajax异步提交form时需要的参数
     2                     var options = {
     3                         url:'<common:webRoot/>/product/attachment/attachmentMultiAction.do?queryType=getAttachmentTotalSize',
     4                         success:successReturn,
     5                         type:'post'
     6                     };
     7                     //ajax异步提交form
     8                     jQuery("#attachmentForm").ajaxSubmit(options);
     9 
    10 
    11 
    12 //ajax返回后回调方法
    13         function successReturn(data){
    14             //后台返回的消息固定为FileTooLarge
    15             if("FileTooLarge" == data){
    16                 var vMessage = "您添加的附件文件总大小超过(<%=AttachmentInfo.ATTACHMENT_SIZE/1024/1024%>M),请压缩文件或者重新选择。";
    17                 alert(vMessage);
    18             }else{//返回消息为空时,则正常提交form,上传文件
    19                 document.attachmentForm.target = "_self";
    20                 document.attachmentForm.action = "<common:webRoot/>/product/attachment/attachmentMultiAction.do";
    21                 document.attachmentForm.submit();
    22                 window.loadingImg.style.visibility = "visible";
    23             }
    24         }

    其中successReturn是返回后调用的方法,如果文件过大则进行提示,否则重新提交,进行上传。

    关于Ajax异步提交表单的详细介绍,会在下一篇文章中介绍。

    这种方法的好处是不受客户端和服务器端的安全性影响,不好的地方是会先进行一个异步提交,需要消耗一定资源,当然因为是异步的,只要不是上传特别大的附件而导致检测过程过长,页面端的响应效果还是没什么太大的影响。

  • 相关阅读:
    css定位
    题解 P2345 【奶牛集会】
    浅谈主席树
    浅谈Manacher算法
    CSP2019 游记
    P5025 [SNOI2017]炸弹
    浅谈2-SAT
    DAY 5模拟赛
    DAY 3
    Luogu P2915 [USACO08NOV]奶牛混合起来
  • 原文地址:https://www.cnblogs.com/ryanchancrj/p/3478672.html
Copyright © 2011-2022 走看看