你的位置:首页 > Java教程

[Java教程]uploadify使用的一些经验总结


说说自己使用uploadify的一波三折的曲折过程:

  之所以要选择uploadify,是源于自己先前使用过jQuery官网的上传文件插件,比较难用(页面写的代码比较多,IE下后台回传需要配置格式【不清楚其他上传插件是否也是这样】),而且一直有IE9上传不成功的问题,到我离开上家公司的时候也一直没有解决这个问题(可能是本人比较low的原因吧)。所以在使用插件之前先调研了一下。uploadify提供两个版本,flash的uploadify和html5的uploadFive。文档还是比较齐全的,网上的使用例子页比较多,配置页比较简单,所以第一选择就是他了。

 

1.初体验

  uploadify的flash版本免费,而且根据以往的经验所有浏览器都支持flash的(这是悲剧的开始),所以计划只使用这个版本就行。

  产品给的效果如下(有三个图片预览框,每一张图片有对应的描述,所以不能用一个上传按钮,每一个上传按钮上传对应的图片)

  

 

  配置完毕后chrome自测通过(中间有个小曲折,产品那边想要多张图片一起上传,当时没有找到IE8展示的处理。后面再网上找到了一篇,然后录了下来图片上传前预览)。

  要测试各个浏览器的情况,在Firefox上一看,我晕,Firefox最新的版本根本没有自带flash插件,结果就是连file input的样式都没有更改,完全没有作用。先前是想加入一段dom

<object data="xxx.swf" height="0" width="0"></object>

  让浏览器检测到有flash文件弹出安装flash的提示。后来想一想不行啊,为了上传个文件让用户去装flash,太复杂了。

  最后决定判断让支持html5的使用uploadiFive上传,不支持的才使用uploadify(flash)版本上传。

if(window.applicationCache){//支持html5    

在配置uploadify的过程中遇到两个问题:

  1.file input元素是有name属性的,但是使用flash后需要手动传递过去,也就是fileObjName这个属性,配置uploadiFive也需要传递这个name。

  2.fileSizeLimit设置文件大小貌似没有起到作用。最后只能自己验证(onSelect事件中验证),验证失败也需要自己处理取消上传(因为我是配置了自动上传的'auto': true)

//swf上传需要在onUploadError处理这个失败$('#' + opts.fileObjName).uploadify('cancel');

 

  执行取消后还需要在onUploadError事件中截取这个取消事件导致触发视为onUploadError事件

    'onUploadError': function(file, errorCode, errorMsg, errorString) {      if(errorCode != -280){//取消上传的错误码是-280        $.dialog.error('上传失败,请重试',{txtYes: '我知道了'});      }            }

  下面是我的uploadify的配置

/*依赖于jQuery和$.dialogopts = {  fileObjName:'idCardPositive',  swf: 'uploadify/uploadify.swf',  showProgress: function(progress){},//progress:0-1  checkFile: function(file){},  normalOnSelect: function(){},  normalUploaded: function(id,data),  positionClass: 'file-btn-left',}*/function init(opts){  var maxSize = 5242880;//1024 * 1024 * 5,5M  $('#' + opts.fileObjName).uploadify({    'fileSizeLimit ': maxSize,    'multi': false,//每次只能选择一个文件    'auto': true,/*如果是自动上传,那上传按钮将没用了*/    'fileTypeExts': '*.jpg;*.bmp;*.jpeg;*.png',    'fileTypeDesc': '请选择图像或者视频',    'queueID': 'fileQueue',    'width': 200,    'height': 140,    'buttonText': '',    'fileObjName': opts.fileObjName,//需要修改文件名称    'swf': opts.swf,    'uploader': '/pcapi/user/uploadUserChangeCardImage.htm',    'onSelect' : function(file) {      //有name表示是swf格式文件上传,html5文件上传参数请参考http://www.uploadify.com/documentation/uploadifive/onselect-2/      //需要检测文件类型和大小      if(opts.checkFile(file)){        opts.normalOnSelect(opts.positionClass);      }else{        //swf上传需要在onUploadError处理这个失败        $('#' + opts.fileObjName).uploadify('cancel');      }    },    'onUploadProgress': function(file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) {      opts.showProgress(bytesUploaded/bytesTotal);                },    'onUploadError': function(file, errorCode, errorMsg, errorString) {      if(errorCode != -280){//取消上传的错误码是-280        $.dialog.error('上传失败,请重试',{txtYes: '我知道了'});      }            },    'onUploadSuccess': function(file, data) {      opts.normalUploaded(opts.fileObjName,data);    }  });}

 

在配置uploadiFive的时候遇到一个问题:

  1.fileTypeExts设置为“*.jpg;*.bmp;*.jpeg;*.png”,但实际上所有的图片格式都可以选择。所以只能在选择图片后自己手动检测格式。而且由于onSelect的参数queue没有文件类型信息:点击查看。所以只能在onAddQueueItem事件中检测,然后在onSelect中取消上传队列queue来取消文件的自动上传

    'onAddQueueItem': function(file) {//html5需要自己检测格式和大小      fileCheckResult = opts.checkFile(file);    },    'onSelect' : function(queue) {      if(fileCheckResult){        opts.normalOnSelect(opts.positionClass);      }else{        $('#' + opts.fileObjName).uploadifive('clearQueue');      }    },

  可能还有一个问题是需要配置'fileType': 'image/*',因为我直接设置了,不知道不设置会不会有问题,没试

  下面是我的uploadiFive配置

/*依赖于jQuery和$.dialogopts = {  fileObjName:'idCardPositive',//name和id相同  showProgress: function(progress){},//progress:0-1  checkFile: function(file){},  normalOnSelect: function(positionClass){},  normalUploaded: function(id,data),  positionClass: 'file-btn-left',}*/function init(opts){  var fileCheckResult = true;  var maxSize = 5242880;//1024 * 1024 * 5,5M  $('#' + opts.fileObjName).uploadifive({    'fileSizeLimit ': maxSize,    'multi': false,//每次只能选择一个文件    'auto': true,/*如果是自动上传,那上传按钮将没用了*/    'fileTypeExts': '*.jpg;*.bmp;*.jpeg;*.png',    'fileTypeDesc': '请选择图像或者视频',    'queueID': 'fileQueue',    'width': 200,    'height': 140,    'buttonText': '',    'fileObjName': opts.fileObjName,//需要修改文件名称    'dnd': false,//不允许拖拽    'fileType': 'image/*',    'uploadScript': '/pcapi/user/uploadUserChangeCardImage.htm',    'onAddQueueItem': function(file) {//html5需要自己检测格式和大小      fileCheckResult = opts.checkFile(file);    },    'onSelect' : function(queue) {      if(fileCheckResult){        opts.normalOnSelect(opts.positionClass);      }else{        $('#' + opts.fileObjName).uploadifive('clearQueue');      }    },    'onProgress': function(file, e) {      opts.showProgress(e.loaded / e.total);    },    'onError': function(file, errorCode, errorMsg, errorString) {      $.dialog.error('上传失败,请重试',{txtYes: '我知道了'});    },    'onUploadComplete': function(file, data) {      opts.normalUploaded(opts.fileObjName,data);    }  });}

 

 

2.当头棒喝

  本地测试OK以后,放到测试环境上去测试,马上被震惊了。

  遇到的第一个问题就是在IE下很多时候点击没有反应(没有弹出文件选择框),找了半天原因终于找到了:必须在文档准备完全的时候再去初始化uploadify,而且确保上传input是可用的(非display:none)

  好了,可以选择文件了,但是选择文件以后IE8/9总是抛出call to startUpload failed异常,去网上查了一下,主要有几个原因

  1.而是可能有多个上传的div或者input(含有相同的name或者ID)导致的,如果有两个不同的上传按钮,那么他们的name,id要设置得不一样。

  2.flash跨域导致(flash上传源码文件和页面所在的域不同【静态资源现在统一放在static.xxx.com服务器下】)。我的原因是这个,我按照网上说的使用在服务器的根目录(主域名所在工程的根目录)下防止了crossdomain.最终我的解决方案是不让其跨域,我将uploadify资源放在了主域名所在工程的根目录下,然后请求这个目录下的uploadify.swf文件。好了,最终终于能够上传文件了。

 

   最终是解决了上传的问题,花费的时间也不少,记录下来,希望后面有用uploadify的童鞋能够少走一些弯路。