如何解决swfupload的“

JavaScript010

如何解决swfupload的“,第1张

一、准备工作

从官网上下载发布版v2.2.0.1,仅取下载文件中的SWFUpload.js和swfupload.swf即可,另外可利用官网上的DEMO,从中获取一张PNG图片。

swfupload.swf是上传组件的核心,一个特制的FLASH,具有浏览文件,上传文件的功能,以按钮形式体现在用户眼前,上文中提及的PNG图片浮在按钮上,可增强视觉效果。SWFUpload.js与swfupload.swf交互,向开发者提供操作接口。

二、使用步骤

文档中指出,SWFUpload并不是拖放式的上传控件,它需要使用者具备JavaScript(以下简称JS)和DOM的知识,进行UI界面的设计。

点击“选择文件”按钮,文件对话框即刻跳出,用户选择多个文件后,对话框立即关闭,选择的文件进入排队序列,等待上传。当调用SWFUpload 对象的startUpload方法执行上传命令。在此例中,swfu已经实例化为SWFUpload 对象,故可以在JSP中添加一个按钮,在其点击事件中调其该方法。在JSP中添加代码:

<button onclick="swfu.startUpload()">上传</button>

虽如此,但文件没有上传到服务器上,至少客户端不知道上传的目的地。

3.指定客户端将上传信息发送至服务器的URL——struts2登场

swfupload将upload_url属性值作为客户端将文件上传请求信息发送至服务器的URL,读者可理解为struts2表单中的action属性值,upload_url属性值默认为web项目的主页。笔者仅介绍struts2如何接收请求。

struts2已经实现了上传功能,笔者不作详细介绍(由于struts2实现了无缝整合,开发者仅需要将上传的临时进行复制即可,其使用方法易于掌握)。

使用struts2的上传功能,开发者需要知道file标签的name属性值,在此基础上,编写action类即可,并在struts.xml文件中配置名字其名字。在swfupload中,file标签的name属性等价为file_post_name属性,其默认值为Filedata。至此,具备了URL和name属性值,便可开始struts2整合之旅。

首先将action的名字赋值给 swfupload中upload_url属性。接着编写自己的action类,类中包含两个属性Filedata和Filename,Filedata和file_post_name值相同(文档推荐使用默认值Filedata)。 Filedata指向了struts2上传的临时文件路径(action中的execute函数执行完毕,临时文件将被删除),Filename为上传文件的名字。Execute函数实现将临时文件复制到指定的目录(此例将它放在WEB项目下bin目录下的upload中)。此例action的名字为“upload”,在JSP中将upload_url属性赋值为upload。

4.添加捕获事件函数

swfupload仅实现了后台操作,前台的处理空间留给了开发者,它采用事件触发机制,让开发者捕获特定事件,并鼓励开发者自定义对应的事件处理函数(笔者定义为:捕获事件函数)进行相应处理。即当swfupload内部某一特定事件发生,便触发JS函数,JS函数通过回调机制将函数参数继续传入自定义的JS函数中。Swfupload通过固定的事件函数名属性值寻找自定义的JS函数,所以在初始化工作中,将自定义的JS函数名赋值给swfupload指定的对应属性即可。

比如,当你选择上传文件后,文件对话框随即关闭,产生关闭对话框完成的事件,内置的fileDialogComplete函数被触发,函数执行完必要的操作后,将整个参数信息传入file_dialog_complete_handler属性值对应的JS函数。所以,开发者仅需将自定义的JS函数名赋值给file_dialog_complete_handler属性即可。Swfupload向外提供的所有事件以及对应的函数定义,文档有详细说明。笔者将“添加捕获XXX事件函数”定义为:自定义JS函数用来捕捉XXX事件,XXX表示swfupload内部捕获事件函数,并函数名赋值给XXX事件对应的属性。比如“添加捕获fileDialogComplete事件函数”表示先自定义JS函数(假设函数名为fileDialogCompleteHandler),用来捕获fileDialogComplete事件,并且将fileDialogCompleteHandler赋值给fileDialogComplete事件对应的属性file_dialog_complete_handler。

为便于管理,笔者建议新建一个JS文件,专门用来存放捕获事件函数,此例为handler.js,注意在JSP中要将其引入。

<script type="text/javascript" src="handler.js"></script>

5.实现批量上传

swfupload不自动批量上传,读者可以尝试选择两个文件点击上传按钮,在服务器端却仅有一个文件,当再次点击上传按钮后,服务器端又多出一个文件。Swfupload虽支持批量上传,但本质仍是单个文件依次上传,这有别于传统设计模式,但其益处却避免了开发者编写大量代码,迭代分析所选文件。

文档指出,添加捕获uploadComplete事件函数(其对应属性为upload_complete_handler),并在其中调用上传函数startUpload,通过递归的方式实现批量上传,即在某个文件上传完成后,再次启动文件上传。此例,该函数被定义为uploadComplete。

在JSP中添加upload_complete_handler属性并赋值为uploadComplete。

6.显示上传文件列表

显示出上传文件列表能够增强用户体验,因为用户将看见选择的文件信息。下文介绍将选择的文件以表格形式显示出来,每行内容为依次为文件名、大小、状态(QUEUED、ERROR、COMPLETE)。

读者不妨在文档中仔细查找是否存在其参数包含file类型集合的API函数,其结果必然徒劳,因为只有参数为file类型的API函数。这在上文已有介绍:swfupload本质依靠单个文件形式上传。该知识点对于对于灵活掌握swfupload举足轻重。故当选择某一文件后,在表格追加显示该文件信息,在文件对话框关闭后,显示表格(表格初始状态为隐藏,在JSP中定义)。

三、从页面跳转到请求流程

此时,本应划上句号,因为所选文件已经上传到upload目录下,但笔者还是想就部分朋友反映“上传完成后,页面不跳转”现象谈谈个人观点。页面不跳转是一个不争的事实,你大可反复尝试。难道这意味着struts2页面跳转功能失效呢?笔者在没搞清楚swfupload原理前,也为之困扰。struts2页面跳转功能仍然良好地在运转,不过它将跳转的页面回响至swfupload,swfupload用内置函数uploadSuccess捕获。对此,理解用户从访问上传页面到页面跳转的整个请求过程至关重要。

首先浏览器访问WEB服务器,打开上传页面,这个过程和打开网页原理相同。当点击“选择文件”按钮后,浏览器通过JS启用swfupload后退出舞台,flash登场。当点击“上传”按钮,flash模拟浏览器向WEB服务器发起连接(新开session),向WEB服务器发送上传信息。可见,当WEB服务器返回信息,目的地不是浏览器,而是flash。整个过程,flash始终和JS紧密交融,将发生的事件通知JS,给开发者留下了足够的编程空间。这不得不赞叹swfupload,将flash设计得淋漓尽致,将JS、WEB服务器、浏览器天衣无缝融入一体。

当WEB服务器响应代码为200时(swfupload表示上传成功的默认代码,可通过修改http_success属性值改变),swfupload便产生上传成功事件,故可通过添加捕获上传成功事件函数得到struts2返回的页面,但不可通过uploadError事件处理struts2拦截器抛出的异常信息,因为swfupload无法解析WEB服务器返回的信息,它仅靠WEB服务器返回代码产生相应事件。

上传成功事件对应的内置函数为uploadSuccess(file object, server data, received response),其中第一个参数为上传的文件,第二个参数为服务器返回的数据,第三个参数为布尔值,从字面上看,估计表示是否收到信息。struts2跳转的页面以HTML代码形式赋值给第二个参数,故可在该捕获事件函数中,置入document.write(server_data)语句,实现页面跳转。

笔者认为swfupload并不希望开发者这样做,因为单个文件的上传机制将导致出现上传完一个文件页面就跳转一次的荒唐现象。其实,只要任何时候调用document.write方法,swfupload立即失效,切忌这样做。

对于实现批量上传成功页面跳转的方法,笔者建议可将server_data缓存,在捕获uploadSuccess事件函数中,如果上传队列为空(getStats().files_queued >0),再用document.write向swfupload say Goodbye。

随意花的博客 - CSDN博客

2020年3月22日示例(找vue项目router路由目录下的model目录下的所有js文件,不会再向下找子集目录,然后在ind...

CSDN编程社区

Vue实现文件上传(带进度条和取消上传功能)

2021年9月30日在创建一个vue文件,将上述封装方法引入,代码如下: <template>附件上传: 附件

www.cncsto.com

...导入导出(前端部分) - 今天又有什么bug的博客 - CSDN博客 - vue导入

7月7日首先,我们写一个导入按钮, 然后给他添加点击事件importData(): <el-buttontype="primary"ic...

CSDN编程社区

对某个文件取消自动导入vue -