文件上传
1、文件上传插件
1.1 简介
Uploadify是JQuery的一个上传插件,支持多文件上传,实现的效果非常不错,带进度显示。
1.2 使用
1.2.1引入uploadify所依赖的js文件
<script type="text/javascript"src="<%=basePath %>lib/jquery/jquery-1.5.2.min.js" </script> <script type="text/javascript"src="<%=basePath%>lib/uploadify/jquery.uploadify.min.js"> </script> <script type="text/javascript" src="<%=basePath%>lib/uploadify/swfobject.js"> </script> |
1.2.2页面上HTML代码
<input type="file" name="uploadify"id="uploadify" class = "uploadify" style = "border :0"/>
<div style = "position : absolute;top :20px;right : 20px;z-index:100;" id = "fileQueue"></div>
1.2.3页面上的JS代码
$(document).ready(function() { $("#uploadify").uploadify({ 'uploader' : 'fileUpload.do;jsessionid=${pageContext.session.id}', 'swf' : 'lib/uploadify/uploadify.swf', 'cancelImg' : 'lib/uploadify/uploadify-cancel.png', //'folder' : 'uploads',//您想将文件保存到的路径 'queueID' : 'fileQueue',//与html元素的id对应 //'queueSizeLimit' : 5, 'fileTypeDesc' : 'xsn文件', 'fileTypeExts' : '*.xsn;', //控制可上传文件的扩展名,启用本项时需同时声明fileTypeDesc 'auto' : true, 'progressData':'percentage', 'multi' : true, 'queueSizeLimit' : 10, 'preventCaching' : false, 'height': 30, 'width' : 180, 'fileSizeLimit' : '1MB', 'buttonText' : '上传文件(xsn类型文件)', 'overrideEvents':['onSelectError','onQueueComplete','onDialogClose'], //'buttonImage' : 'lib/images/upload.png', 'onSelectError' : function(file, errorCode, errorMsg) {//当文件选定发生错误时触发 var msgText = "上传失败\n\n"; switch(errorCode) { case -100: msgText += "单次上传的文件最多 "+this.settings.queueSizeLimit+" 个"; break; case -110: msgText += "文件大小超过限制( "+this.settings.fileSizeLimit+" )"; break; case -120: msgText += "文件大小为 0,不可上传"; break; case -130: msgText += "文件格式不正确,限 "+this.settings.fileTypeExts; break; default: msgText += "错误代号:"+errorCode+"\n"+errorMsg; } $.ligerDialog.error(msgText); }, 'onUploadError' : function(file, errorCode, errorMsg, errorString){ stop(); if(errorCode==-280||errorCode==-290) //使用者自己取消的动作不再跳讯息窗口 { return ; } var msgText = "上传失败\n\n"; switch(errorCode) { case -200: msgText += "HTTP 错误\n"+errorMsg; break; case -210: msgText += "上传文件遗失,请重新操作"; break; case -230: msgText += "安全性错误\n"+errorMsg; break; case -240: msgText += "上传文件数量最多 "+this.settings.uploadLimit+" 个"; break; case -250: msgText += "上传失败\n"+errorMsg; break; case -260: msgText += "找不到指定文件的ID,请重新操作"; break; case -270: msgText += "参数错误"; break; case -280: msgText += file.name+"\n文件上传被取消"; break; case -290: msgText += file.name+"\n文件上传被停止"; break; default: msgText += "文件:"+file.name+"\n错误代号:"+errorCode+"\n"+errorMsg+"\n"+errorString; } $.ligerDialog.error(msgText); }, 'onQueueComplete' : function(stats) {//当队列中的所有文件全部完成上传时触发 if(stats.uploadsErrored == 0){ //$.ligerDialog.success('成功上传' + stats.uploadsSuccessful + '个文件'); $.ligerDialog.success('上传成功'); f_reload(); } else { //$.ligerDialog.error('有' + stats.uploadsErrored + '个文件出错'); $.ligerDialog.error('上传出错'); } }, 'onFallback()' :function() {//当文件选定发生错误时触发 $.ligerDialog.error("当前浏览器不支持flash"); }, 'onDialogClose':function(){} }); }); |
1.2.4 Uploadify 3.2 参数属性、事件、方法函数详解
一、属性 |
| ||
属性名称 |
默认值 |
说明 | |
auto |
true |
设置为true当选择文件后就直接上传了,为false需要点击上传按钮才上传。 | |
buttonClass |
” |
按钮样式 | |
buttonCursor |
‘hand’ |
鼠标指针悬停在按钮上的样子 | |
buttonImage |
null |
浏览按钮的图片的路径。 | |
buttonText |
‘SELECT FILES’ |
浏览按钮的文本。 | |
checkExisting |
false |
文件上传重复性检查程序,检查即将上传的文件在服务器端是否已存在,存在返回1,不存在返回0 | |
debug |
false |
如果设置为true则表示启用SWFUpload的调试模式 | |
fileObjName |
‘Filedata’ |
文件上传对象的名称,如果命名为’the_files’,PHP程序可以用$_FILES['the_files']来处理上传的文件对象。 | |
fileSizeLimit |
0 |
上传文件的大小限制,如果为整数型则表示以KB为单位的大小,如果是字符串,则可以使用(B, KB, MB, or GB)为单位,比如’2MB’; 如果设置为0则表示无限制 | |
fileTypeDesc |
‘All Files’ |
这个属性值必须设置fileTypeExts属性后才有效,用来设置选择文件对话框中的提示文本,如设置fileTypeDesc为“请选择rar doc pdf文件” | |
fileTypeExts |
‘*.*’ |
设置可以选择的文件的类型,格式如:’*.doc;*.pdf;*.rar’。 | |
formData |
|
JSON格式上传每个文件的同时提交到服务器的额外数据,可在’onUploadStart’事件中使用’settings’方法动态设置。 | |
height |
30 |
设置浏览按钮的高度,默认值 | |
itemTemplate |
false |
用于设置上传队列的HTML模版,可以使用以下标签: | |
method |
Post |
提交方式Post或Get | |
multi |
true |
设置为true时可以上传多个文件。 | |
overrideEvents |
|
设置哪些事件可以被重写,JSON格式,如:’overrideEvents’ : ['onUploadProgress'] | |
preventCaching |
true |
如果为true,则每次上传文件时自动加上一串随机字符串参数,防止URL缓存影响上传结果 | |
progressData |
‘percentage’ |
设置上传进度显示方式,percentage显示上传百分比,speed显示上传速度 | |
queueID |
false |
设置上传队列容器DOM元素的ID,如果为false则自动生成一个队列容器。 | |
queueSizeLimit |
999 |
队列最多显示的任务数量,如果选择的文件数量超出此限制,将会出发onSelectError事件。 | |
removeCompleted |
true |
是否自动将已完成任务从队列中删除,如果设置为false则会一直保留此任务显示。 | |
removeTimeout |
3 |
如果设置了任务完成后自动从队列中移除,则可以规定从完成到被移除的时间间隔。 | |
requeueErrors |
false |
如果设置为true,则单个任务上传失败后将返回错误,并重新加入任务队列上传。 | |
successTimeout |
30 |
文件上传成功后服务端应返回成功标志,此项设置返回结果的超时时间 | |
swf |
‘uploadify.swf’ |
uploadify.swf 文件的相对路径。 | |
uploader |
uploadify.php |
后台处理程序的相对路径。 | |
uploadLimit |
999 |
最大上传文件数量,如果达到或超出此限制将会触发onUploadError事件。 | |
width |
120 |
设置文件浏览按钮的宽度。 |
二、事件 |
| |
事件名称 |
说明 | |
onCancel(file) |
当点击文件队列中文件的关闭按钮或点击取消上传时触发,file参数为被取消上传的文件对象 | |
onClearQueue(queueItemCount) |
当调用函数cancel方法时触发,queueItemCount参数为被取消上传的文件数量。 | |
onDestroy() |
当destory方法被调用时触发 | |
onDialogClose(queueData) |
当文件浏览框关闭时触发,如果将此事件被重写,则当向队列添加文件上传出错时不会弹出错误消息提示。 queueData对象包含如下属性: · filesSelected 文件选择对话框中共选择了多少个文件 · filesQueued 已经向队列中添加了多少个文件 · filesReplaced 已经向队列中替换了多少个文件 filesCancelled 取消了多少个文件 filesErrored 出错了多少个文件 | |
onDialogOpen() |
当文件选择对话框弹出时立即出发,但可能在文件选择对话框被关闭之前并不能全部执行。 | |
onDisable() |
当disable方法禁用Uploadify上传按钮时被调用时触发。 | |
onEnable() |
当disable方法启用Uploadify上传按钮时被调用时触发。 | |
onFallback() |
当Uploadify初始化过程中检测到当前浏览器不支持flash时触发。 | |
onInit() |
首次初始化Uploadify结束时触发。 | |
onQueueComplete(queueData) |
文件上传队列处理完毕后触发。 queueData对象包含如下属性: · uploadsSuccessful –上传成功的文件数量 uploadsErrored –上传失败的文件数量 | |
onSelect(file) |
选择文件后向队列中添加每个上传任务时都会触发。 | |
onSelectError(file, errorCode, errorMsg) |
选择文件后向队列中添加每个上传任务时如果失败都会触发。 file –文件对象 errorCode –错误代码如下: · QUEUE_LIMIT_EXCEEDED –任务数量超出队列限制; · FILE_EXCEEDS_SIZE_LIMIT –文件大小超出限制; · ZERO_BYTE_FILE –文件大小为0 · INVALID_FILETYPE –文件类型不符合要求 errorMsg –错误提示,可通过’this.queueData.errorMsg’定制 | |
onSWFReady() |
Flash文件载入成功后触发。 | |
onUploadComplete(file) |
每个文件上传完毕后无论成功与否都会触发。 | |
onUploadError(file, errorCode, errorMsg, errorString) |
文件上传出错时触发,参数由服务端程序返回。 | |
onUploadProgress(file, bytesUploaded, bytesTotal, totalBytesUploaded, totalBytesTotal) |
处理上传队列的过程中会多次触发此事件,每当任务状态有更新时都会触发。 · file –文件对象 · bytesUploaded –已上传的字节数 · bytesTotal –文件总字节数 · totalBytesUploaded –当前任务队列中全部文件已上传的总字节数 totalBytesTotal –当前任务队列中全部文件的总字节数 | |
onUploadStart(file) |
当文件即将开始上传时立即触发 | |
onUploadSuccess(file, data, response) |
当文件上传成功时触发 · file –文件对象 · data –服务端输出返回的信息 response –有输出时为true,如果无响应为false,如果返回的是false,当超过successTimeout设置的时间后假定为true | |
overrideEvents |
如果对原有的事件处理方式不满意,我们可以对其记性重写,格式如下:'overrideEvents':['onSelectError','onQueueComplete','onDialogClose'] |
三、方法 | ||
方法名称 |
说明 |
应用举例 |
cancel(fileID, suppressEvent) |
取消队列中的任务,不管此任务是否已经开始上传 · fileID –要取消的文件ID,如果为空则取消队列中第一个任务,如果为’*'则取消所有任务 suppressEvent –是否阻止触发onUploadCancel事件,当清空队列时非常实用。 |
<a href="javascript:$(‘#file_upload’).uploadify(‘cancel’)">取消第一个</a> <a href="javascript:$(‘#file_upload’).uploadify(‘cancel’, ‘*’)">清空队列</a> <a href="javascript:$(‘#file_upload’).uploadify(‘upload’, ‘*’)">开始上传所有任务</a> |
destroy() |
销毁Uploadify实例并将文件上传按钮恢复到原始状态 |
<a href="javascript:$(‘#file_upload’).uploadify(‘destroy’)">销毁Uploadify实例</a> |
disable(setDisabled) |
禁用或启用文件浏览按钮 setDisabled –设置为true表示禁用,false为启用 |
<a href="javascript:$(‘#file_upload’).uploadify(‘disable’, true)">禁用按钮</a> <a href="javascript:$(‘#file_upload’).uploadify(‘disable’, false)">启用按钮</a> |
settings(name, value, resetObjects) |
获取或设置Uploadify实例参数 · name –属性名称,如果只提供属性名称则表示获取其值 · value –属性值 resetObjects –设置为true时,更新postData对象将清空现有的值。否则,新的值将被添加到其末尾。 |
$(‘#file_upload’).uploadify(‘settings’,'buttonText’,'BROWSE’); $(‘#file_upload’).uploadify(‘settings’,'buttonText’)); |
stop() |
停止当前正在上传的任务 |
<a href="javascript:$(‘#file_upload’).uploadify(‘upload’, ‘*’)">开始上传</a> <a href="javascript:$(‘#file_upload’).uploadify(‘stop’)">停止上传</a> |
upload(fileID) |
立即上传指定的文件,如果fileID为’*'表示上传所有文件,要指定上传多个文件,则将每个文件的fileID作为一个参数 |
<a href="javascript:$(‘#file_upload’).uploadify(‘upload’,'*’)">开始上传所有文件 |
2、文件上传后台处理
import java.util.Map; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.ModelAndView; import org.springframework.util.FileCopyUtils;
@RequestMapping("/fileUpload") public ModelAndView fileUpload(HttpServletRequest request,HttpServletResponse response) throws Exception { //使用MutipartFile MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; //获取文件信息的MAP Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) { MultipartFile mf = mutipartFile; String fileName = mf.getOriginalFilename(); String newFileName = UUID.randomUUID().toString().replace("-", "") + "_" + fileName; //在服务器端新建文件(ctxPath表示服务器端存储文件的路径) File uploadFile = new File(ctxPath + SEPARATOR + newFileName); try { // 把要上传的文件内容复制到新建的文件中 FileCopyUtils.copy(mf.getBytes(), uploadFile); } catch (Exception e) { e.printStackTrace(); } } return null; } |
3 常见问题及解决方法
1、302错误
1)、查看浏览器是否安装Flash插件,如果没有请安装Flash插件;
2)、Flash上传文件时SESSION丢失的问题(swfupload)
在 IE 下,上传工具能够工作,而一到 Firefox 下,SWFUpload 就会提示错误 302。通过从 Fiddler 抓包,发现上传文件的请求被 302 重定向到了登陆页面,所以无法正常上传文件。也就是说,之前用户登陆后的 session 信息在 Flash 发送的上传请求中丢失了。于是我们对文件上传功能做了一定的修改:在用户进入上传页面时,就把当前的 session ID 写到页面中,作为 JavaScript 变量拼接到 SWFUpload 上传文件的目标 URL 中,Flash 就可以利用我们人工传入的 JSESSIONID 来维持登陆状态了。当开始上传时,Flash 通过自己的连接通道向服务器发送数据,但是因为请求的路径中包含了 session 信息所以可以和浏览器的 session 状态保持同步,服务器可以通过 URL中的 sessionID 来获取用户登录的信息。如上所示:
'uploader': 'fileUpload.do;jsessionid=${pageContext.session.id}'。
2、上传数量超过限制的数量时弹出提示框问题,如下图
原因是uploadify插件使用默认的onSelectError事件,解决方法是使用overrideEvents参数重写onSelectError事件,同理,我们可以使用该参数重写一个指定的事件。
3、如何隐藏进度条?
修改id为fileQueue的div的style,将display设置为none即可