SWFUpload 文件上传详解
SWFUpload 是一个客户端文件上传工具,最初由 Vinterwebb.se 开发,它通过整合 Flash 与 JavaScript 技术为 WEB 开发者提供了一个具有丰富功能继而超越传统
input type=”file” 标签的文件上传模式。
官方站点:http://www.swfupload.org/
DEMO 地址:http://demo.swfupload.org/
主要特点
- 可以同时上传多个文件;
- 类似 AJAX 的无刷新上传;
- 可以显示上传进度;
- 良好的浏览器兼容性;
- 兼容其他 JavaScript 库 (例如:jQuery, Prototype 等);
- 支持 Flash 8 和 Flash 9;
SWFUpload 不同于其他基于 Flash 构建的上传工具,它有着优雅的代码设计,开发者可以利用 XHTML、CSS 和 JavaScript 来随心所欲的定制它在浏览器下的外观;它还提供了一组简明的 JavaScript 事件,借助它们开发者可以方便的在文件上传过程中更新页面内容来营造各种动态效果。
在使用 SWFUpload 之前,请确认你具备一定的 JavaScript 和 DOM 知识。在实际开发中,大部分的错误都是由于错误的设置和低劣的 Event Handlers 处理程序所造成的。
SWFUpload 的文件上传流程:
- 引入相应的 js 文件
- 实例化 SWFUpload 对象,传入一个配置参数对象进行各方面的配置。
- 点击 SWFUpload 提供的 Flash 按钮,弹出文件选取窗口选择要上传的文件;
- 文件选取完成后符合规定的文件会被添加到上传的队列里;
- 调用 startUpload 方法让队列里文件开始上传;
- 文件上传过程中会触发相应的事件,开发者利用这些事件来更新 ui、处理错误、发出提示等等;
SWFUpload 包括三部分的内容:
SWFUpload.js、swfupload.swf、初始化配置参数及各种事件处理函数。
所以首先在页面引入 SWFUpload.js
在页面中实例化一个 SWFUpload 对象:
var swfu; |
我们看到要实现一个 SWFUpload 上传功能很简单,就是实例化一个 SWFUpload 对象。但繁琐的地方就在于实例化实要用到的参数配置对象,以及各种事件的发生时机以和提供的参数。所以重点来了。下面几个表格对开发中要用到的东西列举了出来,虽然已经蛮多了,但并不是 SWFUpload 的全部,我列出来的只是常用的。要查看完整的文档,请到 SWFUpload 官网上查询。
配置参数对象中的常用属性及说明
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
upload_url | String | 处理上传文件的服务器端页面的 url 地址,可以是绝对地址,也可以是相对地址,当为相对地址时相对的是当前代码所在的文档地址 | |
preserve_relative_urls | Boolean | false | 如果为 false 则 SWFUpload 会把 swfupload.swf 用到的相对地址转换为绝对地址,以达到更好的兼容性 |
file_post_name | String | Filedata | 相当于用普通的文件域上传文件时的 name 属性,服务器端接收页面通过该名称来获取上传的文件 |
post_params | Object (直接量) | 一个对象直接量,里面的键 / 值对会随着每一个文件一起上传,文件上传要附加一些信息时很有用 | |
use_query_string | Boolean | false | 为 false 时,post_params 属性定义的参数会以 post 方式上传;为 true 时,则会以 get 方式上传(即参数会以查询字符串的形式附加到 url 后面) |
file_types | String | 该属性指定了允许上传的文件类型,当有多个类型时使用分号隔开,比如:*.jpg;*.png , 允许所有类型时请使用 . | |
file_types_description | String | 指定在文件选取窗口中显示的文件类型描述,起一个提示和说明的作用吧 | |
file_size_limit | String | 指定要上传的文件的最大体积,可以带单位,合法的单位有:B、KB、MB、GB,如果省略了单位,则默认为 KB。该属性为 0 时,表示不限制文件的大小。 | |
file_upload_limit | Number | 指定最多能上传多少个文件,当上传成功的文件数量达到了这个最大值后,就不能再上传文件了,也不能往上传队列里添加文件了。把该属性设为 0 时表示不限制文件的上传数量。 | |
file_queue_limit | Number | 指定文件上传队列里最多能同时存放多少个文件。当超过了这个数目后只有当队列里有文件上传成功、上传出错或被取消上传后,等同数量的其他文件才可以被添加进来。当 file_upload_limit 的数值或者剩余的能上传的文件数量小于 file_queue_limit 时,则取那个更小的值 | |
flash_url | String | swfupload.swf 文件的绝对或相对地址,相对地址是指相对于当前的页面地址。实例化 swfupload 后,就不能再改变该属性的值了。 | |
prevent_swf_caching | Boolean | 为 true 时会加一个随机数在 swfupload.swf 地址的后面,以阻止 flash 影片被缓存,这是为了防止某些版本的 IE 浏览器在读取缓存的 falsh 影片时出现的 bug | |
button_placeholder_id | String | 指定一个 dom 元素的 id, 该 dom 元素在 swfupload 实例化后会被 Flash 按钮代替,这个 dom 元素相当于一个占位符 | |
button_placeholder | DOMElement | 指定一个 dom 元素,该 dom 元素在 swfupload 实例化后会被 Flash 按钮代替,这个 dom 元素相当于一个占位符。当 button_placeholder_id 与 button_placeholder 都存在时,以 button_placeholder_id 为优先 | |
button_image_url | String | 指定 Flash 按钮的背景图片,相对地址或绝对地址都可以。该地址会受到 preserve_relative_urls 属性的影响,遵从与 upload_url 一样的规则。该背景图片必须是一个 sprite 图片,从上到下包含了 Flash 按钮的正常、鼠标悬停、按下、禁用这四种状态。因此该图片的高度应该是 Flash 按钮高度的四倍 | |
button_width | Number | 指定 Flash 按钮的宽度 | |
button_height | Number | 指定 Flash 按钮的高度,应该为 button_image_url 所指定的按钮背景图片高度的 1/4 | |
button_text | String | 指定 Flash 按钮上的文字,也可以是 html 代码 | |
button_text_style | String | Flash 按钮上的文字的样式,使用方法见示例 | |
button_text_top_padding | Number | 指定 Flash 按钮顶部的内边距,可使用负值 | |
button_text_left_padding | Number | 指定 Flash 按钮左边的内边距,可使用负值 | |
button_disabled | Boolean | false | 为 true 时 Flash 按钮将变为禁用状态,点击也不会触发任何行为 |
button_cursor | 指定鼠标悬停在 Flash 按钮上时的光标样式,可用值为 SWFUpload.CURSOR 里定义的常量 | ||
button_window_mode | 指定 Flash 按钮的 WMODE 属性,可用值为 SWFUpload.WINDOW_MODE 里定义的常量 | ||
file_dialog_start_handler | Function | fileDialogStart 事件侦听函数 | |
file_queued_handler | Function | fileQueued 事件侦听函数 | |
file_queue_error_handler | Function | fileQueueError 事件侦听函数 | |
file_dialog_complete_handler | Function | fileDialogComplete 事件侦听函数 | |
upload_start_handler | Function | uploadStart 事件侦听函数 | |
upload_progress_handler | Function | uploadProgress 事件侦听函数 | |
upload_error_handler | Function | uploadError 事件侦听函数 | |
upload_success_handler | Function | uploadSuccess 事件侦听函数 | |
upload_complete_handler | Function | uploadComplete 事件侦听函数 |
各种事件说明
要实现与用户的交互,靠的就是在这些事件上做文章了
fileDialogStart ( ) |
---|
在文件选取窗口将要弹出时触发 |
fileQueued ( file object ) |
当一个文件被添加到上传队列时会触发此事件,提供的唯一参数为包含该文件信息的 file object 对象 |
fileQueueError ( file object, error code, message ) |
当文件添加到上传队列失败时触发此事件,失败的原因可能是文件大小超过了你允许的数值、文件是空的或者文件队列已经满员了等。该事件提供了三个参数。第一个参数是当前出现问题的文件对象,第二个参数是具体的错误代码,可以参照 SWFUpload.QUEUE_ERROR 中定义的常量 |
fileDialogComplete ( number of files selected, number of files queued, total number of files in the queued ) |
当文件选取完毕且选取的文件经过处理后(指添加到上传队列),会立即触发该事件。可以在该事件中调用 this.startUpload () 方法来实现文件的自动上传参数 number of files selected 指本次在文件选取框里选取的文件数量参数 number of files queued 指本次被添加到上传队列的文件数量参数 total number of files in the queued 指当前上传队列里共有多少个文件(包括了本次添加进去的文件) |
uploadStart ( file object ) |
当文件即将上传时会触发该事件,该事件给了你在文件上传前的最后一次机会来验证文件信息、增加要随之上传的附加信息或做其他工作。可以通过返回 false 来取消本次文件的上传参数 file object 为当前要上传的文件的信息对象 |
uploadProgress ( file object, bytes complete, total bytes ) |
该事件会在文件的上传过程中反复触发,可以利用该事件来实现上传进度条参数 file object 为文件信息对象参数 bytes complete 为当前已上传的字节数参数 total bytes 为文件总的字节数 |
uploadError ( file object, error code, message ) |
文件上传被中断或是文件没有成功上传时会触发该事件。停止、取消文件上传或是在 uploadStart 事件中返回 false 都会引发这个事件,但是如果某个文件被取消了但仍然还在队列中则不会触发该事件参数 file object 为文件信息对象参数 error code 为错误代码,具体的可参照 SWFUpload.UPLOAD_ERROR 中定义的常量 |
uploadSuccess ( file object, server data, received response ) |
当一个文件上传成功后会触发该事件参数 file object 为文件信息对象参数 server data 为服务器端输出的数据 |
uploadComplete( file object ) |
当一次文件上传的流程完成时(不管是成功的还是不成功的)会触发该事件,该事件表明本次上传已经完成,上传队列里的下一个文件可以开始上传了。该事件发生后队列中下一个文件的上传将会开始 |
swfupload 实例的方法
方法中大多数是动态改变参数配置对象的方法
destroy ( ) |
---|
当不需要再使用 SWFUpload 了的时候,可以使用该方法来销毁它的实例和 dom 元素 |
startUpload( file_id ) |
开始上传队列中指定的文件参数 file_id 代表要上传的文件的 id,如果未填写这个参数,则会上传队列中第一个文件 |
cancelUpload ( file_id, trigger_error_event ) |
取消文件的上传参数 file_id 为要取消的文件的 id, 如果该参数为 undefined 或者未填写,则会取消队列里的第一个文件参数 trigger_error_event 接受一个布尔值,当为 false 时取消文件不会触发 uploadError 事件,默认为 true |
stopUpload ( ) |
终止当前正在上传的文件,会触发 uploadError 事件。如果当前没有文件在上传,则该方法什么都不会做 |
getStats ( ) |
获取队列的 stats object |
setStats ( stats_object ) |
修改队列的 stats_object,传入修改过的 stats_object 作为参数 |
getFile ( file_id, index ) |
根据文件 id 或文件索引来获取一个 File Object, 当使用文件 id 时只能获得队列里的文件,当使用文件索引时所有文件(包括队列内和队列外)都可获得 |
addPostParam ( name, value) |
往配置对象中 post_params 指定的附加信息对象中增加键 / 值对 |
removePostParam ( name) |
移除置配置对象中的 post_params 包含的某一个键 / 值对,参数 name 为要移除的值的键名 |
addFileParam ( file_id, name, value) |
为某个特定文件增加随之一起上传的附加信息。注意,只有在该指定的文件上传时,附加的信息才会一起上传。而配置对象中 post_param 设置的附加信息在任一文件上传时都会与之一起发送。参数 file_id 为要指定的文件 id, 参数 name 和 value 分别为附加信息的名称和值 |
removeFileParam ( file_id, name) |
移除通过 addFileParam 方法增加的附加信息,两个参数相信就不用我多讲了吧 |
setUploadURL ( url) |
动态设置配置对象中 upload_url 的值 |
setPostParams ( param_object) |
动态设置配置对象中 post_params 属性的值,新的值会覆盖旧的值。参数 param_object 必须为一个对象直接量,且里面的属性和值都只能为字符串 |
setFileTypes ( types, description) |
动态设置配置对象中 file_types 和 file_types_description 属性的值。两个参数都不能省略 |
setFileSizeLimit ( file_size_limit) |
动态设置配置对象中 file_size_limit 属性的值 |
setFileUploadLimit ( file_upload_limit) |
动态设置配置对象中 file_upload_limit 属性的值 |
setFileQueueLimit ( file_queue_limit) |
动态设置配置对象中 file_queue_limit 属性的值 |
setFilePostName ( file_post_name) |
动态设置配置对象中 file_post_name 属性的值 |
setUseQueryString ( use_query_string) |
动态设置配置对象中 use_query_string 属性的值 |
setButtonImageURL ( url) |
动态设置配置对象中 button_image_url 属性的值 |
setButtonDimensions ( width, height) |
动态设置 Flash 按钮的宽度和高度,两个参数分别为宽度和高度的值,类型为数字,且不能带单位 |
setButtonText ( text) |
动态设置配置对象中 button_text 属性的值 |
setButtonTextStyle ( css_style_text) |
动态设置配置对象中 button_text_style 属性的值 |
setButtonTextPadding ( left, top ) |
动态设置 Flash 按钮的左边内边距和顶部内边距 |
setButtonDisabled ( isDisabled ) |
动态对 Flash 按钮进行禁用和不禁用的操作,参数为一个布尔值 |
setButtonCursor ( buttonCursor ) |
动态设置配置对象中 button_cursor 的值 |
文件信息对象 File Object
在事件监听函数中,经常要用到文件信息对象来获取文件的信息以供下一步的操作
属性 | 类型 | 描述 |
---|---|---|
id | String | SWFUpload 定义的文件 id, 用来控制文件的上传 |
index | Number | 文件的索引,用在 getFile (i) 方法中 |
name | String | 文件的原始名称,不包括路径 |
type | String | 文件类型 |
creationdate | Date | 文件的创建日期 |
modificationdate | Date | 文件的最后修改日期 |
filestatus | Number | 当前文件的状态,详细的请参照 SWFUpload.FILE_STATUS 中定义的常量 |
队列状态对象 Stats Object
用来获取当前队列的状况
属性 | 类型 | 描述 |
---|---|---|
in_progress | Number | 得到的值为 1 或 0,表明当前队列是否有文件正在上传中 |
files_queued | Number | 目前上传队列中的文件数量 |
successful_uploads | Number | 已成功上传 (指触发了 uploadSuccess 事件) 的文件数量 |
upload_errors | Number | 上传失败的文件数量 (包括被取消上传的文件) |
upload_cancelled | Number | 被取消上传的文件数量 |
queue_errors | Number | 触发了 fileQueueError 事件的文件数量 |
一些常量
定义的一些常量,便于理解
常量名 | 描述 |
---|---|
SWFUpload.instances | 该常量是一个对象,代表一个页面上所有的 SWFUpload 实例的引用的集合,用 SWFUpload 实例的 movieName 属性进行索引 |
SWFUpload.movieCount | 页面上存在的 SWFUpload 实例的数量 |
SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED | 用户选取的文件超过了允许的数量 |
SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT | 文件的体积超过了允许的大小 |
SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE | 文件是空的 |
SWFUpload.QUEUE_ERROR.INVALID_FILETYPE | 不允许的文件类型 |
SWFUpload.UPLOAD_ERROR.HTTP_ERROR | 服务器返回的状态码不是 200 |
SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL | 没有设置 upload_url |
SWFUpload.UPLOAD_ERROR.IO_ERROR | 读取或传输文件时发生错误 |
SWFUpload.UPLOAD_ERROR.SECURITY_ERROR | 上传受到了安全方面的限制 |
SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED | 上传的文件数量超过了允许的最大值 |
SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED | 上传出现错误 |
SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND | 给 startUpload () 方法传入的文件 id 不存在 |
SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED | uploadStart () 方法中返回了 false |
SWFUpload.UPLOAD_ERROR.FILE_CANCELLED | 上传被取消了 |
SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED | 上传被终止了 |
SWFUpload.FILE_STATUS.QUEUED | 文件正在队列中等待上传 |
SWFUpload.FILE_STATUS.IN_PROGRESS | 文件正在上传 |
SWFUpload.FILE_STATUS.ERROR | 文件在添加到队列或是上传的时候出现了错误 |
SWFUpload.FILE_STATUS.COMPLETE | 文件已上传成功 |
SWFUpload.FILE_STATUS. | 文件被取消上传 |
SWFUpload.CURSOR.ARROW | 鼠标以箭头显示 |
SWFUpload.CURSOR.HAND | 鼠标以手形显示 |
SWFUpload.WINDOW_MODE.WINDOW | Flash 按钮会显示在页面的所有 dom 元素上面 |
SWFUpload.WINDOW_MODE.OPAQUE | 允许其他 dom 元素覆盖住 Flash 按钮 |
SWFUpload.WINDOW_MODE.TRANSPARENT | 允许 Flash 按钮透明显示 |
struts2+swfUpload 简单例子
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> |
Upload.action
package com.action; |
Web.xml
<?xml version="1.0" encoding="UTF-8"?> |
Struts.xml
<?xml version="1.0" encoding="UTF-8" ?> |
SWFUpload 的上传过程中各个步骤的显示方式要改变;我们需要往服务器传递参数;需要从服务器返回参数;这些问题上面的例子都没有解决。
看下面这个图片,这是我在项目中的 SWFUpload 上传附件的效果(其实仿的是 126 邮箱做的)。
上传完成。(上传成功的附件不消失,上传发生错误文件消失。)
删除:删除上传完成的文件(删除后文件逐渐消失)。
SWFUpload 如何改 upload 控件的样式
修改上传 flash 按钮样式
SWFUpload Demo 文件中提供了一个 XPButtonUploadText_61x22.png 图片文件
重新制作一个类似的图片文件替换它。
如果你做的这个图片文件的长款与原图不同,不要忘记修改
/ 按钮的处理 |
修改上传队列附件样式
这个东西的构建是通过 fileprogress.js 文件和 defaut.css 来完成的。
function FileProgress(file, targetID) { |
每当我们选择一个文件上传时它就会 new FileProgress (file, this.customSettings.progressTarget);
根据上面的代码分析其实就是在网页中添加了以下 html 代码
<div id=file.id class="progressWrapper"> |
这段代码会被插入下面这段代码里面
<div class="fieldset flash" id="fsUploadProgress1"> |
如果你的 css 和 javascrpt 能力很强,动态在页面中创建对象改变这个控件的外貌是不是很容易呢。
选择好事件重写事件代码就 ok 了。
不过提醒一下,不要改变现有的这些对象的顺序,您看下后面的代码就这道了。
this.fileProgressElement.childNodes[3].className = "progressBarInProgress"; |
如何控制上传队列中的文件消失(hidden)情况
// Fades out and clips away the FileProgress box. |
这段代码是 FileProgress 文件 disappear 的属性代码。
1) 如果想上传后FileProgress不消失
在 fileprogress.js 文件找到下面代码,像我一样注释掉最后 3 行就 ok 了。当然你也可以在相应的事件中重写函数。
FileProgress.prototype.setComplete = function () { |
2) 删除的时候让 FileProgress 消失
在 fileprogress.js 文件中增加
FileProgress.prototype.setDelete = function () { |
在删除事件中调用即可。
SWFUpload 向服务器传递参数
- SWFUpload 传递参数有 3 中方式:
1、在 url 后加连接:
upload_url: "<%=basePath%>upload?action=up", |
2、使用 swfupload 传递参数,在 setting 中配置
post_params: { |
3、采用 swfupload 的函数:
addPostParam("myFileName",encodeURI(file.name));//这个是我用来传递文件名称的 |
我的方法是修改了一下 uploadStart 函数
function uploadStart(file) { |
SWFUpload 接受服务器 Action 返回的参数
- 首先我们要了解这个函数
function uploadSuccess(file, serverData) { |
file 为上传的文件对象,我们可以获得,file.id、file.name、file.type、file.size 等信息。
serverData 的意思是服务器返回的数据,如果你指定页面,那服务器返回的应该就是这个 jsp 的数据了,这里最好用 type=json 的格式
action 代码
//…… |
struts.xml
<package name="upload"[color=red] extends="json-default" [/color]namespace=""> |
这个配置会出现一个 bug(如果你以前没用过 json 插件的话)
当前使用 struts2.23 版本,使用了 jsonplugin-0.3x.jar 报错
引用
java.lang.ClassNotFoundException: com.opensymphony.xwork2.util.TextUtils
解决:
在下载好的 Struts2 的 lib 文件夹里找到了以下 jar 包:
引用
json-lib-2.x.jar
struts2-json-plugin-2.x.x.jar
struts2-junit-plugin-2.x.x.jar
上面三个包加入项目里之后,再删除 jsonplugin-0.3x.jar 包
SWFUpload 中文乱码问题
- 在网上搜的帖子,关于这个问题的解决方法有很多。
第一种:fileName= new String (fileName.getBytes ("UTF-8"),"GBK");
用这种方式能解决大部分乱码,但如果文件名中有特殊字符和标点符号有时候会转不过来。
第二种:我使用的是这种办法,测试已经通过
/**在设置时需要设置一下上传事件 |
在 action 中使用
fileName = URLDecoder.decode(fileName, "UTF-8"); |
第三种:配置 web.config 配置文件这种方法我没试,不知道行不行。