Actionscript3 文件上传组件制作
现在网站开发中,使用flash作为上传工具已经很普遍了。他的优势也是不言而喻的。其中我最钟意的一点就是可以看到上传进度。
前段时间,用as3写了个swf跟页面元素交互上传文件到服务器。
然后是js设置:
前段时间,用as3写了个swf跟页面元素交互上传文件到服务器。
先来个效果图看看。
Html页面上部署swf:
<div class="container" align="left" style="padding-top:0;"> <object id="longan" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="500" height="65"> <param name="movie" value="${base}/resource/component/upload/longan.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#fdf7f7" /> <embed src="${base}/resource/component/upload/longan.swf" id="longan" bgcolor="#bee2c2" name="longan" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="500" height="65" ></embed> </object> </div>
然后是js设置:
<script language="JavaScript" type="text/javascript"> /*获取swf*/ function getFlashMovie() { var movieName="longan"; if (window.document[movieName]){ return window.document[movieName]; }else if (navigator.appName.indexOf("Microsoft")==-1){ if (document.embeds && document.embeds[movieName]) return document.embeds[movieName]; }else{ return document.getElementById(movieName); } } var setting={ url:"${base}/document/upload;jsessionid=${sessionID}",//这里换成你想要的路径 fileTag:"select:*.txt;*.doc;*.docx;*.xls;*.ppt;*.rar;*.zip", fileExt:"${allowExt}",//可以上传的文件类型*.txt;*.doc;*.docx;*.xls;*.ppt;*.rar;*.zip fileName:"upload_file",//file maxFileNumber:1, maxSize:${maxUploadSize},//最大上传文件大小 logoText:"欢迎使用Longan上传工具!",//提示信息 params:"doc_id=${doc_id}&flash=1",//参数,格式:doc_id=1 response:"File.response",//返回数据时回调 debug:true //debug模式 } //debug模式下的回调函数,名字不能更改 function longan_debug(s){ document.getElementById("debug").innerHTML+=s; } function init(){ try{ //调用swf中的setParams() 这个是在swf中定义的。 //之所以要不断调用,是因为可能swf还没有加载成功。 getFlashMovie().setParams(setting); }catch(e){ setTimeout("File.init();",2000); } } //初始化上传组件 window.onload=init; </script>
好了,看下actionscript 中是怎样与 js交互的:
/* =============================================================== JS 交互 =============================================================== */ public function initJS():void{ ExternalInterface.addCallback("setParams",initParams); } public function initParams(s:Object):void{ this.url=s.url; this.fileExt=s.fileExt; this.fileName=s.fileName; this.fileTag=s.fileTag; this.maxFileNumber=s.maxFileNumber; this.maxSize=s.maxSize; this.debug=s.debug; this.logoText=s.logoText; this.params=s.params; this.response=s.response; if(this.logoText) this.label.text=this.logoText; if(this.debug){ toJSDebug(getParamsInfo()); } } public function toJSDebug(s:String):void{ if(ExternalInterface.available){ ExternalInterface.call("longan_debug",s); } } public function getParamsInfo():String{ var s:String="参数设置成功!<br />"; s+="URL:"+url+"<br />"; s+="文件格式:"+fileExt+"<br />"; s+="文件数:"+maxFileNumber+"<br />"; s+="文件大小限制:"+maxSize+"<br />"; s+="debug模式:"+debug+"<br />"; s+="post参数:"+params+"<br />"; s+="server response function:"+response+"<br />"; return s+"<br />"; } /* ================================================================= end JS 交互 ================================================================= */
在ExternalInterface 中添加对外api。
上传文件的代码:
/** * 上传文件 * */ public function sendFile(e:MouseEvent):void{ if(this.url==""){ error("上传的URL不明确!"); return ; } data.decode(this.params); request = new URLRequest(this.url); request.method=URLRequestMethod.POST; request.data=data; this.timeout=new Date().time; this.file.upload(request,this.fileName); addProgress(); this.loading=true; this.sendButton.enabled=false; this.button.enabled=false; }
----------------------------------------------------------
注意点:
----------------------------------------------------------
1.设置swf的上传路径时,一般需要验证session是否已经有登录,不然不能接收上传的文件。这时就需要添加一个sessionId的参数,比如在jsp中,可以这样:
/document/upload;jsessionid=${sessionID}
2.在<embed/>标签中一定要添加 name 属性,不然js是不能获取到swf组件的。
3.上传时,需要将 URLRequest的requestMethod设置为POST
这里不给上传附件。。
完整的as代码我就直接帖出来了。。
package { import fl.controls.Button; import fl.controls.Label; import fl.controls.ProgressBar; import fl.controls.ProgressBarMode; import fl.controls.progressBarClasses.IndeterminateBar; import fl.managers.StyleManager; import flash.display.Sprite; import flash.events.DataEvent; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.MouseEvent; import flash.events.ProgressEvent; import flash.external.ExternalInterface; import flash.net.FileFilter; import flash.net.FileReference; import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.net.URLVariables; import flash.text.TextFormat; import mx.events.ModuleEvent; /** * <script type="text/javascript" src="js/file.longan.1.0.js"></script><div><a href="#" onclick="File.toAS();">12465</a></div><div id="debug"></div> * * * longan上传工具(flash版) * 带进度条的上传工具哈。 * 2011-12-27 by 集成显卡 */ [SWF(width="500", height="65", backgroundColor="#fdf7f7")]//定义场景大小 public class longan extends Sprite{ /* 外部设置的参数 */ //上传地址 private var url:String=""; private var fileTag:String="select file"; private var fileExt:String="*.*"; //上传文件的name private var fileName:String="fileArea"; private var maxFileNumber:int=1;//最大文件数 private var debug:Boolean=false;//是否开启debug模式 private var maxSize:uint=10*1024*1024; private var logoText:String="welcome! by:集成显卡";//初始时显示的文字 private var params:String="version=1.0"; private var response:String="";//返回数据时的函数 /* 内置参数 * */ private var L:Object={select:"选择文件",send:"上传"}; private var loading:Boolean=false; private var fileSize:uint=0;//文件大小 private var curSize:uint=0;//当前上传的大小 private var curFile:int=0; private var data:URLVariables = new URLVariables(); private var timeout:Number; /* 组件 * */ private var request:URLRequest; private var button:Button; private var sendButton:Button; //进度条 private var progressBar:ProgressBar; private var label:Label; private var infoLabel:Label; //上传主要 private var file:FileReference; public function longan(){ init(); } public function init():void{ initStyle(); initUI(); initJS(); } /* =============================================================================== JS 交互 =============================================================================== */ public function initJS():void{ ExternalInterface.addCallback("setParams",initParams); } public function initParams(s:Object):void{ this.url=s.url; this.fileExt=s.fileExt; this.fileName=s.fileName; this.fileTag=s.fileTag; this.maxFileNumber=s.maxFileNumber; this.maxSize=s.maxSize; this.debug=s.debug; this.logoText=s.logoText; this.params=s.params; this.response=s.response; if(this.logoText) this.label.text=this.logoText; if(this.debug){ toJSDebug(getParamsInfo()); } } public function toJSDebug(s:String):void{ if(ExternalInterface.available){ ExternalInterface.call("longan_debug",s); } } public function getParamsInfo():String{ var s:String="参数设置成功!<br />"; s+="URL:"+url+"<br />"; s+="文件格式:"+fileExt+"<br />"; s+="文件数:"+maxFileNumber+"<br />"; s+="文件大小限制:"+maxSize+"<br />"; s+="debug模式:"+debug+"<br />"; s+="post参数:"+params+"<br />"; s+="server response function:"+response+"<br />"; return s+"<br />"; } /* =============================================================================== end JS 交互 =============================================================================== */ /** * 设置字体 * */ public function initStyle():void{ var txt:TextFormat=new TextFormat(); txt.size=13; StyleManager.setStyle("textFormat",txt); } /** * 设置界面 * */ public function initUI():void{ this.button=new Button(); this.button.label=L.select; this.button.width=80; this.button.x=340; this.button.y=5; this.button.addEventListener(MouseEvent.CLICK,selectFile); this.sendButton=new Button(); this.sendButton.label=L.send; this.sendButton.width=60; this.sendButton.x=430; this.sendButton.y=5; this.sendButton.addEventListener(MouseEvent.CLICK,sendFile); this.sendButton.enabled=loading; this.label=new Label(); this.label.text=""; this.label.x=5; this.label.y=5; this.label.height=30; this.label.width=310; this.infoLabel=new Label(); this.infoLabel.text=""; this.infoLabel.x=5;this.infoLabel.y=45; this.infoLabel.width=480; this.progressBar=new ProgressBar(); this.progressBar.x=5; this.progressBar.y=30; this.progressBar.setSize(480,15); this.progressBar.mode=ProgressBarMode.MANUAL; this.progressBar.indeterminate=false; addChild(label); addChild(button); addChild(sendButton); addChild(this.infoLabel); } /** * 选择文件 * */ public function selectFile(e:MouseEvent):void{ if(!canUpload()){ error("已经达到了上传数量限制!不能再上传文件了"); return ; } if(!loading){ file = new FileReference(); file.addEventListener(ProgressEvent.PROGRESS, onProgress); file.addEventListener(Event.SELECT, onSelect); file.addEventListener(Event.COMPLETE, completeHandle); file.addEventListener(IOErrorEvent.IO_ERROR,onLoadError); file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,returnData); this.file.browse(new Array(new FileFilter(fileTag,fileExt))); } } /**是否可以上传*/ public function canUpload():Boolean{ return curFile<maxFileNumber; } public function error(s:String):void{ infoLabel.htmlText="<font color='#fd5555'>"+s+"</font>"; } public function onProgress(e:ProgressEvent):void{ curSize=e.bytesLoaded; infoLabel.text = "已上传 "+Math.round(e.bytesLoaded/1024) + " / "+Math.round(e.bytesTotal/1024)+" KB"; progressBar.setProgress(curSize,fileSize); } public function onLoadError(e:IOErrorEvent):void{ this.button.enabled=true; this.loading=false; error("上传出错!"+e); } public function onSelect(e:Event):void{ var name:String=file.name; this.fileSize=file.size; this.label.text=name+" 大小:"+Math.round(this.fileSize/1024)+" KB"; if(allowSize()){ this.sendButton.enabled=true; }else{ error("选择的文件太大,最大的文件大小为:"+this.maxSize/1024+" Kb"); return ; } } public function completeHandle(e:Event):void{ this.button.enabled=true; this.loading=false; error("完成!用时:"+(new Date().time-timeout)+" 毫秒"); this.curFile++; } public function returnData(e:DataEvent):void{ trace(e.data); if(this.debug){ toJSDebug("upload success!"+e.data); } if(ExternalInterface.available){ ExternalInterface.call(response,e.data); } } /** * 上传文件 * */ public function sendFile(e:MouseEvent):void{ if(this.url==""){ error("上传的URL不明确!"); return ; } data.decode(this.params); request = new URLRequest(this.url); request.method=URLRequestMethod.POST; request.data=data; this.timeout=new Date().time; this.file.upload(request,this.fileName); addProgress(); this.loading=true; this.sendButton.enabled=false; this.button.enabled=false; } public function addProgress():void{ if(curFile==0){ addChild(progressBar); } } public function allowSize():Boolean{ return this.fileSize<=this.maxSize; } } }