最近项目中要求使用HTTP作文件上传,并且要求有进度显示,在网上东找西寻了半天,解决方案倒也很多,好比使用Ajax上传,但感受这种方式的进度提示 太麻烦,因此没有采用,后来看到了SWFUpload,就找了些资料来看,以为符合本身的要求,研究了足有两天,略有心得,忙不迭地记录下来,以防止时间 长了遗忘,若是不当心帮助了别人,那就更好了,呵呵...javascript
下面摘抄一段SWFUpload官网的介绍(别人翻译过来的):css
SWFUpload 最初是由Vinterwebb.se 开发的客户端文件上传工具。它结合javascript和flash在浏览器中提供一个优于传统上传标签 <input type="file" /> 的功能(和良好的用户体验)。html
SWFUpload 的主要特性:java
SWFUpload 的设计理念与其余基于flash的上传工具不一样。SWFUpload 给开发者尽量多的UI控制能力. 开发者可使用 XHTML, CSS, JavaScript 来使它更符合本身网站的样式风格. 它提供一组简单的js事件更新上传状态,开发者能够根据这些事件来在网页中显示文件上传进度
jquery
好了,夸奖的话很少说了,既然它这么受欢迎,想必是有必定优点的。web
下面记录一下我作的一个小示例,先预览一下程序运行效果:浏览器
有朋友索要例子源码,其实我早已放在个人资源里了,并无设置下载积分,有须要的朋友请到这里下载:http://download.csdn.net/detail/zhangyihui1986/4538748服务器
如今SWFUpload项目托管于Google code下,URL为:http://code.google.com/p/swfupload/ ,请自行下载,下载的压缩文件中含有一个文档,里面详细介绍了SWFUpload的配置参数、事件支持、支持方法等。cookie
这里是官网上的几个例子:http://demo.swfupload.org/网络
网络上关于SWFUpload的博客资源不少,但不少博客质量不过高,并且转来转去,内容重复,因此我在查资料的时候没有找到太合适的资源,后来找到了这里:http://webdeveloperplus.com/jquery/multiple-file-upload-with-progress-bar-using-jquery/ ,这是一个外国人写的关于SWFUpload的小教程,UI作地也挺好,因而我就参照着作了个小例子。
不过,上面连接的教程是针对SWFUpload一个针对JQuery的插件写的,这个插件地址为:http://blogs.bigfish.tv/adam/2009/06/14/swfupload-jquery-plugin/,该插件好像仅仅是完善了一下SWFUpload的事件机制,使用它可采用JQuery的链式写法,但我没有用它,而是用的原生的SWFUpload2.2版本。
很少说,先贴出来我作的例子,而后再针对代码做适当解释。
例子使用了Struts2.3.4做为后台,固然,SWFUpload是不选择后台的,您可使用任意的技术,只要是能实现HTTP协议便可。
1)将下载的压缩文件解压并拷到web项目中(此处我放到项目的js目录下),创建其它资源(如JSP、Action等)后目录结构以下图所示:
2)在JSP文件中引入SWFUpload依赖的JS文件
在此处我用到了ligerUI框架,若是不使用它,那么仅须要引jquery和swfupload.js两个文件便可。
3)JSP文件中HTML结构
4)JSP文件中CSS,给文件上传进度列表赋与样式,我对CSS不够熟悉,此处的样式几乎所有来自于前面那个教程,仅做了一些小的变更。若是您以为这还不够好,那您本身来实现漂亮的UI界面吧!
5)JSP中的Javascript,主要是建立SWFUpload组件实例,并绑定监听函数,在监听函数中处理进度提示:
SWFUpload组件的实例化很简单,就是new一个JS对象,如
咱们须要传给它一个配置对象,这个配置对象的内容不少,详细介绍请参照使用说明文档,在此仅介绍几个重要一些的配置参数,以注释的形式写在代码里。
须要注意的是按钮的高和宽必定要指定,不然flash没法显示。
swfupload仅实现了后台操做,前台的处理空间留给了开发者,它采用事件触发机制,让开发者捕获特定事件,自定义对应的事件处理函数进行相应处理。 即当swfupload内部某一特定事件发生,便触发相应的JS函数,并传入合适的相关参数,开发者就能够拿着这些参数来更新UI界面以提示上传进度了。 Swfupload经过固定的事件函数名属性值寻找自定义的JS函数,因此在初始化工做中,将自定义的JS函数名赋值给swfupload指定的对应属性 便可。
默认状况下,你选择了文件并关闭了文件选择对话框文件并不会自动开始上传,你须要调用SWFUpload的startUpload()方法,该方法接收一个file_id做为参数,若是参数为空,则自动开始上传文件队列中的第一个文件。
另外,在全部的事件监听器中,this关键字都是指向SWFUpload对象,因此你能够在file_queued_handler或file_dialog_complete_handler等事件监听器中这样开始文件上传:
默认状况下,你在第3步中开始了一个文件上传,可是若是你选择的是多个文件,那么你会发现这个文件上传后其它文件并不会自动开始上传,这是为何呢?原来 Swfupload虽支持批量上传,但本质还是单个文件依次上传,因此若是你的上传是支持多个文件上传那只有你本身去开始其它文件的自动上传了,咱们能够 在upload_complete_handler事件监听器中再调用一个startUpload()方法:
由于upload_complete_handler事件是在一个文件上传后触发,无论该文件是否上传成功都会触发该事件,因此咱们在这里再调用一次startUpload方法是合适的,这样SWFUpload组件在前一个文件上传完成后就会自动开始下一个文件的上传。
显示出上传文件进度列表可以加强用户体验,由于用户将看见选择的文件信息以及该文件的上传进度,这些东西就彻底由开者来定制了,SWFUpload组件将 丰富的文件信息及上传进度在调用事件监听函数时以参数的形式传进来,咱们就能够利用这些信息动态更新文件上传进度UI了。如前面的例子咱们在 file_queued_handler事件监听函数中将文件信息及其进度条拼接到页面的ol列表中,在upload_start_handler事件监 听函数中初始化进度条显示,而后在文件上传过程当中会不停地触发upload_progress_handler事件,咱们就在这个事件监听函数中获取上传 进度,并将其更新到进度列表,这样即可实现文件上传的进度提示。在SWFUpload丰富的事件机制支持下,实现这些东西是很容易的事。
在SWFUpload的配置参数中有一个post_params参数是用来向后台传递参数的,默认状况好像是不能传递参数的,可是若是你将另外一个配置参数use_query_string设置为true以后就能够传递参数了。
该参数接收一个JS对象,相似于这样:
可是若是参数值中含有中文的话,那么后台会报错,也取不到值,能够这样解决:
在JS中先用UTF-8进行中文编码
而后在后台再转回来,在Java中就体现为
如此即可解决中文参数传递问题。
假设有这种需求:文件上传完成后跳转到指定的页面,好比文件信息查看页面,那咱们可能会一时找不到好的方法,由于SWFUpload上传相似于Ajax上 传,涉及到的上传交互操做并不是是浏览器所发,而是由Flash发出的上传请求,那么后台给出的跳转信息浏览器天然接收不到,而是由Flash接收到了,既 然浏览器接收不到跳转信息,那么自动跳转就不会发生。
对于这种需求,咱们能够参照Ajax提交跳转的方式,在后台成功接收文件后输出一些信息,好比跳转的页面,或者仅仅是一个字符串,而把跳转的任务交由 Javascript来完成,那么咱们应该在什么事件监听函数中处理呢!您能够看看upload_success_handler这个事件的回调函数有什 么参数,以下:
这个事件发生后会传三个参数到咱们定义的监听函数中,第一个是上传完成的文件对象(关于文件对象可参看SWFUpload的文档,其实就是一个JS对象, 包含一些重要的文件信息),第二个实际上是服务器返回的数据,若是后台用的直接跳转,那么这里的server data就会是跳转页面的HTML结构,document.write()将其输出,也算是完成跳转了吧!若是你仅仅是向前台输出个字符串,并无跳转, 那么这里就应该是你输出的字符串,在这里就能够用location.href=“来实现跳转;第三个参数是Boolean类型,表示是否接收到服务器传回 的数据。
须要注意的是该事件在每一个文件上传成功均会触发,若是同时在上传多个文件,那么第一个文件上传完成后页面就直接跳转了,后台的文件也就得不到机会上传了, 因此这里须要判断一下队列里是否还有没有上传完成的文件,若是没有了再跳转,就能够了,至于如何判断队列里是否还有未上传的文件,这里用到了 SWFUpload的另外一个对象Stats。该对象提供了上传队列的状态信息,访问实例的getStats方法可获取此对象,该对象中有一些属性,其中有 一个files_queued属性能够表示是否还有未上传的文件,若是该属性为0则表示所有上传,能够这样作
最近在使用SWFUpload过程当中发现一个问题,文件上传成功后我须要将其移动到指定目录下,因为目录信息是在Session中的,这时在非IE浏览器 中出现了问题,Session中没有东西,用户登陆信息也没有了。通过调试才发现文件上传成功后在后台取到的Session与用户登陆完成后的 Session相比根本就不是一个Session了,它们的ID不一样,也就是说文件上传另生成了一个Session,而这个Session是全新的,固然 没有了登陆时存放的信息了。
通过一番搜索,这是因为Flash Player在非IE浏览器下一个Bug引发的,这里有一段描述:
Cookie issue
On Windows the Non-IE Flash Player plugin (FireFox, Opera, Safari, etc) sends the IE cookies regardless of the browser used. This breaks authentication and sessions for many server-side scripting technologies.
Developers should manually pass Session and Authentication cookie information and manually restore Sessions on the Server Side if they wish to use Sessions
The SWFUpload package contains work-around sample code for PHP and ASP.Net
也就是说非IE浏览器下Flash Player插件发送的也是IE浏览器当前页面的cookie,而且Session是靠Cookie中保存的SessionId实现的,所以后台处理程序另新建了Session,程序也就出现了上述错误。
找到的解决办法是手动将SessionID传到后台服务端。
在上传路径URL里加上jsessionid变量便可,以下:
这样就能够解决问题了,有人还说可使用SWFUpload组件的一个插件:swfupload.cookies.js,但我没有弄好,看它的源码是分 析浏览器的cookie而后将它们拼接到post_params配置项中,我手动拼上jsessionid也是不起做用,不知道是否是本身没弄对,反正是 这个插件我没有成功使用。
http://www.wonima.com正在举行投稿发帖送iphone、以及现金活动,绝对新鲜