“js+flash上传组件”客户端验证文件大小

来源:互联网 发布:刻录光碟的软件 编辑:程序博客网 时间:2024/05/29 15:09

 

一,在看文章之前,需要了解的:

1.上传文件时,可以等上传完成之后验证文件大小。如果文件是G数量级的,或许在几个小时后才收到验证结果是可能是。

(如果你想批判这一条,请看下文);

2.验证所有文件的大小。可以采用验证整个request的大小。

方法:

long totalLength = request.getContentLength();

弊端:A.表单中不仅有文件,还有其它数据,检验的文件大小就不准确;

     B.不能验证单独文件的大小

3.验证单个文件:不必等用户上传几个G后才提示文件过大。假如限制单个文件为20M,等上传到20M时就提示文件过大;

(那么上传上去的20M就白白浪费了)

4.js不能获取文件大小,也不能获取file表单的文件路径;

5.利用ActiveX可以获取文件大小,但是需要降低浏览器的安全级别(每次打开浏览器都提示"安全性太低"。不现实);

6.flash不能获取文件的路径。AS3的Air才可以用File对象获取文件路径,但flash用的是FileReference对象(获取不到路径);

7.flash中不能用全路径获取本地文件(只能靠表单来选择);

8.flash可以获取文件大小、创建日期、修改日期等属性。

9.flash可以在“文件选择对话框”中过滤文件类型。

如下图:你可以只允许选择图片

 

 

二,flash组件制作

1.准备

Adobe Flash CS4.下载链接就不再贴了。

最终效果如下:

2.新建

新建一个ActionScript3.0的flash文件,场景大小设置为550x25。

注意到,图中有个FPS.

【ps】FPS:帧率,默认是1,以这个速度,你可以在“发布预览”中自己体验一下,生动得说:运行很“卡”。一般设置为30就可可以了;

3.拖放组件

找到“组件”小窗,没有的话,到“窗口”中勾选。

拖放一个“TextInput”组件、两个button组件、一个Label组件,依次放在场景上。

设置长宽分为为:

300x22;50x22;50x22;120x22;

 

4.组件命名

A.选中(点击)第一个按钮,在“属性”小窗。

修改组件名字为:browseBtn。

找到“组件检查器面板”按钮。

修改label的值为“浏览...”

B.同方法,修改第二个按钮的名字为clearBtn,label为“清除”。

C.同方法,修改输入框的名字为fileName,editable为"false",禁止输入。

D.同方法,修改Label组件的名字为fileSize.

 

三,ActionScript脚本的编写

1.准备

选中任何一个组件,在“属性”小窗,调出ActionScript面板。

出现“动作-帧”小窗,如下:

选中“场景1”-->“图层1:帧1”,右侧出现脚本编辑器。

 

【ps】[请认真阅读,以避免没必要的错误]

 

2.源码,初期demo

先贴出优化前,可以运行的代码:

【ps】看代码前,请选明确:

A.url后面请先不要加&xx=xx的参数(稍后会讲解)

B.此demo只是体验下基本语法、按钮动作、文件过滤

C.认识两个神器FileReference与ExternalInterface,前者是文件信息的封装类,后者是与js交互的类。

D.如果不成功,或弹出flash的“安全设置”,请把生成的swf放到实际项目中(本地的swf操作文件或js的话会有安全限制);

E.如果web项目用的域名访问,请在此demo的url中也用同样的域名;如果web项目是用ip访问的,这里也用ip;保持一致就可以了;最好用域名;(要不然,错了都不知道从哪里找)。

F.上传文件时参数名是“Filedata”,在页面流、逻辑流或者servlet用此变量接收。

G.请再web项目中加断点调试

 

 

var file: FileReference;var filter:FileFilter;var isSelect:Boolean;var urlRequest:URLRequest=new URLRequest();urlRequest.url = "http://xx.xxxxx.com/appname/com.xxxxxx.utils.XxxXxx.flow"; //修改urlfile = new FileReference();filter = new FileFilter("doc/docx/xls/xlsx/ppt/pptx/txt/jpg/gif/png/rar/zip", "*.doc;*.docx;*.xls;*.xlsx;*.ppt;*.pptx;*.txt;*.jpg;*.gif;*.png;*.rar;*.zip");file.addEventListener(Event.COMPLETE, complete);file.addEventListener(Event.OPEN,open);file.addEventListener(Event.SELECT,select);file.addEventListener(ProgressEvent.PROGRESS,onProgress);browseBtn.addEventListener(MouseEvent.CLICK,selectFile);//browseBnt.addEventListener(MouseEvent.ROLL_OVER,onOver);//browseBnt.addEventListener(MouseEvent.ROLL_OUT,onOut);browseBtn.buttonMode=true;///uploadBtn.addEventListener(MouseEvent.CLICK,uploadFile);//uploadBnt.addEventListener(MouseEvent.ROLL_OVER,onOver);//uploadBnt.addEventListener(MouseEvent.ROLL_OUT,onOut);///uploadBtn.buttonMode=true;clearBtn.addEventListener(MouseEvent.CLICK,clearFile);/*function onOver(e:MouseEvent){e.currentTarget.gotoAndPlay("over");}function onOut(e:MouseEvent){e.currentTarget.gotoAndPlay("out");}*/function selectFile(e:MouseEvent):void {file.browse([filter]);}function onProgress(e:ProgressEvent){var loaded:int;loaded=Math.floor(e.bytesLoaded/e.bytesTotal*100);//resultBox.appendText("[文件上传中..."+loaded+"%]\n");}function complete(e:Event):void {//resultBox.appendText("[文件上传已完成!]\n");}function open(e:Event):void {//resultBox.appendText("[连接:已成功连接!]\n");}function select(e:Event):void {var tempTarget = e.target;//var file2:FileReference = e.target as FileReference;isSelect=true;fileName.text = tempTarget.name;//e.target.name;fileSize.text = tempTarget.size + "字节";if(tempTarget.size > 5*1024*1024){  ExternalInterface.call("alert","文件大小过大!!!");}//resultBox.appendText("[文件信息]\n文件名:"+tempTarget.name+"\n文件大小:"+tempTarget.size+"\n文件类型:"+tempTarget.type+"\n文件创建日期:"+tempTarget.creationDate+"\n文件最后修改日期:"+tempTarget.modificationDate+"\n");}function uploadFile(e:Event){//resultBox.appendText("[文件开始上传...]\n");if (isSelect){  file.upload(urlRequest);}else{  //resultBox.appendText("[错误:请先选择要上传的文件!]\n");}}function clearFile(e:Event){//清除isSelect=false;fileName.text = "";fileSize.text = "";}


 

【不能运行?没关系,只要能选择文件,能看到文件大小就可以了,这是初期demo,继续往下看】

 

 

3.代码解析

A.给组件注册事件,代码中的xxx.addEventListener一看便知。

B.file.browse([filter]); 弹出"文件选择"窗口,并过滤掉其他的文件类型。

C.file.upload(urlRequest); 文件用name为Filedata的变量,上传到指定的url.

D.获取文件的大小,在这个函数中: 

function select(e:Event):void {var tempTarget = e.target; //tempTarget.size......} 

四,JavaScript与Flash的通信

1.Flash到JavaScript

A.[AS3代码:]

ExternalInterface.call("alert","文件大小过大!!!");

 

调用js的alert方法。

类似于在js中写:alert("文件大小过大!!!");

B.[AS3代码:]

ExternalInterface.call("connectionStr","字符串1","字符串2");

调用js的connectionStr方法。

[JS代码:]

function connectionStr(str1,str2){alert(str1+""+str2);}

 

【ps】ExternalInterface.call的第二个参数是可变的,可以传多个参数。

C.既然提到了AS中的可变参数,那就举个例子:

function setFlashData(inPara:String, ... args):String{var returnStr = inPara;  for(var i:uint=0; i<args.length; i++) {    returnStr += args[i];   }return returnStr;}

 

如果是往JS变量赋值的话,你懂的..

 

2.JavaScript到Flash

这个通信过程需要在flash中注册回调函数。还是要用到两大神器之一的ExternalInterface.

[AS3代码:]

function uploadOneFile():String {var taStr:String;if (isSelect){  fileSize.text = "文件开始上传";  try{   file.upload(urlRequest);  }catch(e:Error){   fileSize.text = "上传出错!";  }}else{  fileSize.text = "请选择文件";}    taStr = "success";    return taStr;}internal function initApp():void {//标明 uploadOneFile 可以在js中用flash对象通过uploadOneFile名字直接调用ExternalInterface.addCallback("uploadOneFile",uploadOneFile);}initApp();

[JS代码:]

var flash1 = $flash("flashUpload");var reStr = flash1.uploadOneFile();//获取flash对象function $flash(flashId) {    if (navigator.appName.indexOf("Microsoft") != -1 )    {       return document[flashId];    } else {       return window[flashId];    }}

【ps】稍后讲解flash对象怎么来的。

 

如果是js往flash赋值的话,你懂的...只要给AS中的uploadOneFile()添加参数就行了 ,

uploadOneFile(para1:String),

然后js中flash1.uploadOneFile("cmd");

 

 

五,html与Flash对象

html代码:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="<%=request.getContextPath()%>/xxxx/flash_upload.cab#version=9,0,0,0" width="550" height="25" id="flashUpload"  align="middle">    <param name="movie" value="<%=request.getContextPath()%>/xxxx/flash_upload.swf" />    <param name="allowScriptAccess" value="always" />    <param name="swLiveConnect" value="true" />    <param name="wmode" value="opaque"/>    <embed src="<%=request.getContextPath()%>/xxxx/flash_upload.swf" width="550" allowScriptAccess="always" height="25" name="flashUpload" align="middle" type="application/x-shockwave-flash" pluginspage="" wmode="opaque" swLiveConnect="true"/></object>

解析:

1.swf放置的路径,自己解决

2.object标签的id为“flashUpload”,embed的name为“flashUpload”

3.添加变量<param name="wmode" value="opaque"/>

embed中添加 属性  wmode="opaque"

4.注意到3了吗?你可以体验下不加这两个会出现什么情况。

【ps】解决 flash 覆盖弹出div的问题

A.设置div的z-index是不可行的

 B.适应IE<param name="wmode" value="opaque"/>

 C.embed标签中添加wmode="opaque" 适应FF

5.用上文提到的函数 $flash 获取flash对象。这个函数应该还不够完善,请google下,欢迎为本帖留言。

 

 

六.为request添加参数

1.先明确说明:在url后面添加?a=aa&b=bb的方式是不行的。

[AS3代码:]

//在外部设置flash内部的值function setFlashData(inUrl:String,inMax:int,inAll:int, ... args):String{try{  if(null == inUrl || inUrl == ""){   return "null_url";  }  reqUrl = inUrl;  var variables:URLVariables = new URLVariables();  variables._eosFlowAction = args[0];  variables.relationId = args[1];  variables.path = args[2];  variables.filetype = args[3];  /*  for(var i:uint=0; i<args.length; i++) {    reqUrl += args[i]+"&";   }  */  if(inMax > 0){   fileMaxSize = inMax;  }  if(inAll > 0){   fileAllSize = inAll;  }  urlRequest.url = inUrl;  urlRequest.method =  URLRequestMethod.POST;  urlRequest.data = variables;}catch(e:Error){  return "error";}  return "ok";}


 

认真看代码,你懂的...

 

七,样式设置

简单的举例说明:

[AS3代码:]

字体设置:

var myTextFormat:TextFormat = new TextFormat();myTextFormat.bold = false; myTextFormat.color = 0x000000;myTextFormat.size = 12;//browseBtn.label = "浏览...";browseBtn.setStyle("textFormat", myTextFormat);clearBtn.setStyle("textFormat", myTextFormat);fileName.setStyle("textFormat", myTextFormat);fileSize.setStyle("textFormat", myTextFormat);


 

数字输出:

var fileSize_new :Number = 0.0;if(tempTarget.size<1024){  fileSize_new = tempTarget.size;  fileSize.text = fileSize_new + " Byte";}else if(tempTarget.size/1024 < 1024){  fileSize_new = tempTarget.size/1024;  fileSize_new = Number(fileSize_new.toFixed(3));  fileSize.text = fileSize_new + " K";}else{  fileSize_new = (tempTarget.size/1024)/1024;  fileSize_new = Number(fileSize_new.toFixed(3));  fileSize.text = fileSize_new + " M";}


 

 

 

 

 

 

原创粉丝点击