生活随笔
收集整理的這篇文章主要介紹了
《Ext详解与实践》节选:文件上传
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Ext沒提供上傳組件?很多人都會有這疑問。
其實Ext.form.TextField就是Ext的上傳組件的,只要將其配置參數inputType設置為“file”就行了。上傳文件除了文件輸入框,還有一個重要的設置,就是需要將form的enctype屬性設置為“multipart/form-data”。這個也很簡單,在定義FormPanel的時候加入BasicForm的配置參數fileUpload,并設置為true就行了。
在Ext中使用標準上傳方式最大的缺點就是文件輸入框的寬度很難控制,與界面不是太協調,而且在不同瀏覽器中的顯示是不同的。在Ext官方論壇中有很多替代辦法,筆者比較喜歡的是SWFUpload。
SWFUpload使用Flash作為上傳組件,文件選擇可以設置為單選,也可以設置多選,而且可以控制選擇文件的類型。執行文件選擇不依賴于標準文件輸入框,可以使用按鈕、鏈接等多種方式執行,從而可以根據需要設置界面。SWFUpload的提交不依賴Form,其模式類似于Ajax提交,可以很容易的實現對上傳的控制和顯示上傳進度。
SWFUpload的官方地址是:http://www.swfupload.org/。
在SWFUpload中有兩個主要對象:file和Stats。
file對象主要是保存文件的一些基本信息,其結構如下:
{? ??id?:?string,??//?SWFUpload?的文件編號,作為開始上傳、取消上傳的句柄? ??index?:?number,?//?文件在上傳隊列中的索引 ??name?:?string,?//?文件名,不包含路徑 ??size?:?number,?//?文件大小,單位為字節 ??type?:?string,?//?文件類型 ??creationdate?:?Date,?//?文件創建日期 ??modificationdate?:?Date,?//?文件最后編輯日期? ??filestatus?:?number,?//?文件狀態 ??} ? Stats對象主要提供上傳隊列中的信息,其結構如下:
{? ??in_progress?:?number?//?1表示正在上傳文件,0表示則不是 ??files_queued?:?number?//?上傳隊列中的文件數量 ??successful_uploads?:?number?//?已成功上傳的文件數量 ??upload_errors?:?number?//?上傳失敗的文件數量 ??upload_cancelled?:?number?//?取消上傳的文件數量 ??queue_errors?:?number?//?觸發了fileQueueError事件的文件數量 ??} ? 表1列出了SWFUpload的主要配置參數。
表2列出了SWFUpload的主要方法。
要使用SWFUpload,需要在頁面加載swfupload.js文件并設置好參數,尤其要注意Flash文件的路徑。具體使用方法請看下面例子:
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01//EN"?"http://www.w3.org/TR/html4/strict.dtd">??<html?debug='true'>??<head>????<title>上傳文件</title>???????????<meta?http-equiv="content-type"?content="text/html;?charset=utf-8">???????????<link?rel="stylesheet"?type="text/css"?href="../lib/ext/resources/css/ext-all.css"?/>??????????<script?type="text/javascript"?src="../lib/ext/ext-base.js"></script>????<script?type="text/javascript"?src="../lib/ext/ext-all.js"></script>?? ????<script?type="text/javascript"?src="../lib/ext/radiogroup.js"></script>????<script?type="text/javascript"?src="../lib/ext/locale/ext-lang-zh_CN.js"></script>???????????<script?type="text/javascript"?src="swfupload.js"></script>??</head>??<body>???????????<h1?style="margin:20px?0px?0px?20px;">第4章?上傳文件</h1>???????????<br?/>???????????<div?style="padding-left:20px;">??<p>??????<div?id="form1"></div><br>??????<div?>執行操作:</div>??????<textarea?id='op'?rows="10"?style="width:800px;"></textarea>??</p>??<br?/>??</div>??<script>???????????var?app={}; ??? ???????????var?swfu; ??? ??? ???????????Ext.onReady(function(){ ??? ?????????????????????Ext.QuickTips.init(); ?????????????????????Ext.form.Field.prototype.msgTarget?=?'under'; ??? ?????????????????????swfu=new?SWFUpload({ ??????????????????????????????upload_url?:?"upload.ashx",? ??????????????????????????????flash_url?:?"swfupload_f9.swf"?, ??????????????????????????????file_size_limit?:?"10240", ??????????????????????????????file_types?:?"*.jpg;*.gif", ??????????????????????????????file_post_name?:?"Filedata", ??????????????????????????????requeue_on_error?:?false, ??????????????????????????????post_params?:?{}, ??????????????????????????????file_types_description:'圖片', ?????????????????????????????flash_color?:?"#FFFFFF",? ?????????????????????????????file_queued_handler?:?function(file){ ???????????????????????????????????????var?filetype=(file.type.substr(1)).toUpperCase(); ???????????????????????????????????????if(filetype=='JPG'?|?filetype=='GIF'){ ?????????????????????????????????????????????????swfu.startUpload(); ???????????????????????????????????????}else{ ?????????????????????????????????????????????????Ext.Msg.alert('錯誤','只能上傳JPG或GIF格式文件') ???????????????????????????????????????} ?????????????????????????????},? ?????????????????????????????upload_start_handler:function(file){Ext.Msg.progress('上傳文件','正在上傳文件:'+file.name,'0%');return?true;},? ?????????????????????????????upload_progress_handler:function(file,bytesloaded){ ???????????????????????????????????????var?percent?=?Math.ceil((bytesloaded?/?file.size)?*?100); ???????????????????????????????????????Ext.Msg.updateProgress(percent/100,percent+'%'); ?????????????????????????????},? ?????????????????????????????upload_success_handler:function(file,?server_data){ ??????????????????????????????????????var?msg=Ext.decode(server_data); ??????????????????????????????????????if(msg){ ???????????????????????????????????????????????if(msg.success){ ??????????????????????????????????????????????????????????Ext.getCmp('imagePane').body.dom.innerHTML="<img?width='100'?src='upload/"+msg.file+"'>" ??????????????????????????????????????????????????????????Ext.get('op').dom.value+="----------------------------/n" ???????????????????????????????????????????????????????????????????+"執行回調函數:success/n" ???????????????????????????????????????????????????????????????????+"返回值:"+server_data+'/n'; ??????????????????????????????????????????????????????????var?stats=swfu.getStats(); ??????????????????????????????????????????????????????????if(stats.files_queued>0) ?????????????????????????????????????????????????????????????????????????????swfu.startUpload(); ?????????????????????????????????????????????????????????Ext.Msg.hide(); ???????????????????????????????????????????????}else{ ??????????????????????????????????????????????????????????Ext.Msg.alert('錯誤',msg.msg); ???????????????????????????????????????????????} ??????????????????????????????????????}else{ ?????????????????????????????????????????????????Ext.Msg.alert('錯誤','上傳錯誤!') ??????????????????????????????????????} ?????????????????????????????}, ?????????????????????????????upload_error_handler:function(file,error_code,message){ ??????????????????????????????????????Ext.Msg.alert('錯誤','上傳文件“'+file.name+'”發生錯誤。<br>錯誤代碼:'+error_code+'<br>'+'錯誤信息:'+message); ?????????????????????????????}, ?????????????????????????????file_queue_error_handler:function(file,error_code,message){ ???????????????????????????????????????switch?(error_code)?{ ???????????????????????????????????????case?SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: ?????????????????????????????????????????????????Ext.Msg.alert('錯誤',"文件不允許超過300k!<br>?文件名:?"?+?file.name?+?"<br>?大小:?"?+?file.size?); ?????????????????????????????????????????????????break; ???????????????????????????????????????case?SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: ?????????????????????????????????????????????????Ext.Msg.alert('錯誤',"不允許上傳0字節文件!<br>?文件名:?"?+?file.name?+?"<br>?大小:?"?+?file.size?); ?????????????????????????????????????????????????break; ???????????????????????????????????????case?SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED: ?????????????????????????????????????????????????Ext.Msg.alert('錯誤',"已超出上傳文件數量!<br>?文件名:?"?+?file.name?+?"<br>?大小:?"?+?file.size?); ?????????????????????????????????????????????????break; ???????????????????????????????????????case?SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: ?????????????????????????????????????????????????Ext.Msg.alert('錯誤',"不允許上傳該類文件!<br>?文件名:?"?+?file.name?+?"<br>?大小:?"?+?file.size?); ?????????????????????????????????????????????????break; ???????????????????????????????????????default: ?????????????????????????????????????????????????Ext.Msg.alert('錯誤',"發生未知錯誤,錯誤代碼:"+error_code+"!<br>?文件名:?"?+?file.name?+?"<br>?大小:?"?+?file.size?); ?????????????????????????????????????????????????break; ???????????????????????????????????????} ?????????????????????????????} ?????????????????????}); ????????????????????? ????????????????????? ?????????????????????var?frm?=?new?Ext.form.FormPanel({??? ??????????????????????????????applyTo:?"form1", ??????????????????????????????width:?400, ??????????????????????????????height:300, ??????????????????????????????frame:?true, ??????????????????????????????labelWidth:80, ??????????????????????????????labelSeparator:":", ??????????????????????????????title:'上傳文件', ??????????????????????????????fileUpload:true, ??????????????????????????????items:[ ???????????????????????????????????????{ ?????????????????????????????????????????????????xtype:'textfield', ?????????????????????????????????????????????????name:'title', ?????????????????????????????????????????????????fieldLabel:'標題', ?????????????????????????????????????????????????anchor:'-30', ?????????????????????????????????????????????????allowBlank:false ???????????????????????????????????????}, ???????????????????????????????????????{ ?????????????????????????????????????????????????xtype:'textfield', ?????????????????????????????????????????????????name:'Filedata', ?????????????????????????????????????????????????fieldLabel:'文件', ?????????????????????????????????????????????????anchor:'-30', ?????????????????????????????????????????????????allowBlank:false, ?????????????????????????????????????????????????inputType:'file' ???????????????????????????????????????}, ????????????????????????????{layout:'column',border:false,items:[ ??????????????????????????????????????{columnWidth:.4,border:false,items:?[ ??????????????????????????????????????????????????????????{ ???????????????????????????????????????????????????????????????????xtype:'button', ???????????????????????????????????????????????????????????????????text:'上傳文件', ???????????????????????????????????????????????????????????????????handler:function(){ ????????????????????????????????????????????????????????????????????????????swfu.setPostParams({title:frm.form.findField("title").getValue()}); ?????????????????????????????????????????????????????????????????????????????swfu.selectFile(); ???????????????????????????????????????????????????????????????????} ??????????????????????????????????????????????????????????} ?????????????????????????????????????????????????]}, ??????????????????????????????????????{columnWidth:.1,border:false,items:?[ ??????????????????????????????????????????????????????????{xtype:'panel',html:' ',height:26,border:false} ?????????????????????????????????????????????????]}, ??????????????????????????????????????{columnWidth:.4,layout:?'form',border:false,items:?[ ??????????????????????????????????????????????????????????{ ???????????????????????????????????????????????????????????????????xtype:'button', ???????????????????????????????????????????????????????????????????text:'上傳多個文件', ???????????????????????????????????????????????????????????????????handler:function(){ ????????????????????????????????????????????????????????????????????????????swfu.setPostParams({title:frm.form.findField("title").getValue()}); ?????????????????????????????????????????????????????????????????????????????swfu.selectFiles(); ???????????????????????????????????????????????????????????????????} ??????????????????????????????????????????????????????????} ?????????????????????????????????????????????????]} ???????????????????????????????????????]}, ???????????????????????????????????????{ ?????????????????????????????????????????????????xtype:'panel', ?????????????????????????????????????????????????id:'imagePane', ?????????????????????????????????????????????????bodyStyle:'padding:5px', ?????????????????????????????????????????????????html:' ', ?????????????????????????????????????????????????height:120, ?????????????????????????????????????????????????width:120??????????????????????????????????????? ???????????????????????????????????????} ??????????????????????????????], ???????????????buttons:?[{ ???????????????????text:?'保存', ???????????????????scope:this, ???????????????????handler:function(){ ??????????????????????if(frm.form.isValid()){ ???????????????????????????????frm.form.doAction('submit',{ ??????????????????????????????????????????????????????????????????????waitTitle:'上傳文件', ?????????????????????????????????????????????????????????????????????waitMsg:'正在上傳文件……', ?????????????????????????????????????????????????????????????????????????????url:'upload.ashx', ?????????????????????????????????????????????????????????????????????????????method:'post', ?????????????????????????????????????????????????????????????????????????????params:'', ?????????????????????????????????????????????????????????????????????????????success:function(form,action){ ??????????????????????????????????????????????????????????????????????????????????????Ext.getCmp('imagePane').body.dom.innerHTML="<img?width='100'?src='upload/"+action.result.file+"'>" ??????????????????????????????????????????????????????????????????????????????????????Ext.get('op').dom.value+="----------------------------/n" ???????????????????????????????????????????????????????????????????????????????????????????????+"執行回調函數:success/n" ???????????????????????????????????????????????????????????????????????????????????????????????+"返回值:"+Ext.encode(action.result)+'/n'; ?????????????????????????????????????????????????????????????????????????????}, ?????????????????????????????????????????????????????????????????????????????failure:function(form,action){ ??????????????????????????????????????????????????????????????????????????????????????Ext.get('op').dom.value+="----------------------------/n" ???????????????????????????????????????????????????????????????????????????????????????????????+"執行回調函數:failure/n" ???????????????????????????????????????????????????????????????????????????????????????????????+"返回值:"+Ext.encode(action.result)+'/n'; ?????????????????????????????????????????????????????????????????????????????}????????????????????????????????????????????????????????????????????????? ???????????????????????????????}); ??????????????????????} ???????????????????}???????????? ???????????????},{ ???????????????????text:?'取消', ???????????????????scope:this, ???????????????????handler:function(){frm.form.reset();} ???????????????}], ?????????????????????listeners:{ ??????????????????????????????render:function(fp){ ???????????????????????????????????????fpfp.form.waitMsgTarget?=?fp.getEl(); ??????????????????????????????} ?????????????????????} ?????????????????????}); ??? ????????????????????? ???????????})? ??</script>??</body>??</html>? 例子中使用了兩種方式實現文件上傳,一種是標準方式,使用Form提交,一種使用SWFUpload。
標準方式的定義比較簡單,在FormPanel定義中加入fileUpload參數并設置為true,然后將一個TextField的inputType設置為file就行了。保存的提交方式與一般的Form提交沒什么區別。
SWFUpload的定義稍微復雜一點。首先在onReady函數外定義了一個swfu的全局變量,主要目的是使swfu成為一個全局的SWFUpload實例,以便在內部函數中能使用該實例。
本例子使用的Flash 9版本,而且swf文件與頁面文件在同一目錄,所以設置flash_url為swfupload_f9.swf。允許上傳的文件大小限制為10兆,只能上傳JPG和GIF文件,服務器端接收文件的參數名稱為Filedata。
在file_queued_handler函數中先判別上傳文件的擴展名是否符合要求,如果符合則執行startUpload方法開始上傳文件。
upload_start_handler函數在文件開始時顯示一個Ext進度條。
upload_progress_handler函數則根據已上傳字節數計算上傳進度并更新進度條。
upload_success_handler函數根據服務器端返回信息更新頁面顯示,并判斷上傳隊列中是否還有文件未上傳,如果有則繼續上傳。
upload_error_handler函數與file_queue_error_handler函數則在發生錯誤時顯示錯誤信息。
在FormPanel中有兩個按鈕,一個用來演示上傳單文件,一個用來演示上傳多文件。單擊后先根據標題輸入框的值,設置一個附加提交參數title,然后執行selectFile方法或selectFiles方法打開文件選擇對話框。對話框關閉后執行file_queued_handler函數開始上傳文件。
文件上傳后會在id為“'imagePane'”的Panel顯示上傳圖片的縮略圖。執行操作中也會顯示返回的結果。
下面看看服務器端代碼如下:
<%@?WebHandler?Language="C#"?Class="upload"?%>??? ??using?System; ??using?System.Web; ??using?System.Collections; ??using?System.IO; ??using?System.Data.Common; ??using?System.Data; ??? ??? ??public?class?upload?:?IHttpHandler?{ ?????? ??????public?void?Proce***equest?(HttpContext?context)?{ ????????string?outputStr?=?"{success:false,data:''}"; ????????HttpPostedFile?jpeg_image_upload?=?context.Request.Files["Filedata"]; ????????string?title=?context.Request.Form["title"]; ????????string?original_fielname?=?jpeg_image_upload.FileName.ToLower(); ????????string?extname=original_fielname.Substring(original_fielname.LastIndexOf(".")+1,3); ????????if?(extname?==?"gif"?|?extname?==?"jpg") ????????{ ??????????try ??????????{ ???????????????????string?path?=?context.Server.MapPath("./upload"); ????????????DateTime?dt?=?DateTime.Now; ????????????string?newFilename?=?dt.ToString("yyyyMMddHHmmssfff")+"."+extname; ????????????jpeg_image_upload.SaveAs(path+"//"+newFilename); ????????????outputStr?=?string.Format("{{success:true,data:'文件“{0}”上傳成功,文件名:{1}',file:'{1}'}}",title,newFilename); ??????????} ??????????catch(Exception?e) ??????????{ ????????????outputStr?=?string.Format("{{success:false,data:'{0}'}}",e.Message); ??????????} ????????} ????????else ????????{ ??????????outputStr?=?"{success:false,data:'錯誤的文件類型!'}"; ????????} ????????context.Response.Write(outputStr); ???????? ??????} ??? ??????public?bool?IsReusable?{ ??????????get?{ ??????????????return?false; ??????????} ??????} ??? ??} ? 一個很簡單的只接收單文件的服務器端代碼。代碼中使用了客戶端設置的參數Filedata接受文件數據:
| HttpPostedFile jpeg_image_upload = context.Request.Files["Filedata"]; |
代碼中對文件擴展名進行了判斷,如果是GIF或JPG則保存文件,否則返回錯誤。服務器端返回格式使用了Ext的返回格式。 圖1是例子的運行結果。
?
先測試標準方式上傳,在標題輸入測試,然后單擊“選擇”按鈕選擇一幅圖片,單擊保存按鈕。
圖2是文件上傳后的顯示。
?
根據返回值,參數title和文件都已成功上傳。 繼續單擊“上傳文件”按鈕選擇一幅圖片。當選擇文件窗口關閉,會出現一個進度條,可能會是一閃而過,看看返回值:
| ---------------------------- 執行回調函數:success 返回值:{success:true,data:'文件“測試”上傳成功,文件名:20080730174659265.jpg',file:'20080730174659265.jpg'} |
參數titile與文件也同樣正確上傳。 可以繼續單擊“上傳多個文件”測試上傳多個文件的情況,這里就不再贅述了。 SWFUpload和標準模式不同,上傳多個文件時是一個一個的文件上傳的,而不是標準模式使用不同的參數同時上傳。 SWFUpload最大的缺點是受瀏覽器Flash插件版本的限制,低于版本8的Flash插件不起作用。如果使用版本9的swf文件,則需要Flash插件版本為9以上才能用。
總結
以上是生活随笔為你收集整理的《Ext详解与实践》节选:文件上传的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。