劉耀欽
(鄖陽師范高等專科學(xué)校計(jì)算機(jī)科學(xué)系,湖北十堰442000)
利用HTML5拖放技術(shù)實(shí)現(xiàn)多文件異步上傳
劉耀欽
(鄖陽師范高等專科學(xué)校計(jì)算機(jī)科學(xué)系,湖北十堰442000)
在傳統(tǒng)的Web應(yīng)用中實(shí)現(xiàn)本地文件的跨瀏覽器應(yīng)用,不僅要編寫大量冗余代碼,而且很難獲取良好的用戶體驗(yàn)。HTML5利用拖放技術(shù)將本地文件拖放至瀏覽器,通過File API的dataTransfer對(duì)象獲取文件屬性,然后將符合條件的文件添加至由FormData生成的模擬表單中,最后由Ajax的XMLHttpRequest將表單內(nèi)容提交給服務(wù)器,進(jìn)而實(shí)現(xiàn)本地文件的拖放和異步上傳。這極大地提升了用戶體驗(yàn),減輕了服務(wù)器負(fù)載?;谕戏偶夹g(shù)的文件異步上傳是Web應(yīng)用的一種新型技術(shù)形式,有較良好的應(yīng)用前景。
HTML5;拖放;異步;Ajax;File API
在Web應(yīng)用系統(tǒng)中,若要獲得本地文件句柄,需要通過打開對(duì)話框找到文件位置,然后獲取文件路徑,若需要上傳的文件有多個(gè),就需要多次重復(fù)操作,過程不僅繁瑣,而且無法獲得良好的用戶體驗(yàn)。HTML5作為Web前端開發(fā)的新標(biāo)準(zhǔn)超文本標(biāo)記語言,不僅簡(jiǎn)化了傳統(tǒng)HTML標(biāo)簽語法,而且提供了諸如智能表單、離線緩存、Canvas繪圖、拖放等核心技術(shù)和相應(yīng)的API,相比以前版本的HTML,HTML5極大地改善和增強(qiáng)了用戶體驗(yàn)和開發(fā)功能[1],降低了瀏覽器對(duì)資源的占有率以及對(duì)插件的依賴[2],解決了HTML4在Web應(yīng)用功能上的欠缺[3]。其中的拖放技術(shù)和File API既實(shí)現(xiàn)了同一Web頁面內(nèi)部不同對(duì)象之間的拖放,又建立起了本地文件與Web頁面之間的關(guān)聯(lián),使得多文件直接拖放上傳成為可能。
Ajax的Xm lHttpRequest[4]對(duì)象具有對(duì)HTTP協(xié)議的完全訪問能力,包括對(duì)POST、HEAD以及GET等請(qǐng)求處理的能力,用來實(shí)現(xiàn)發(fā)送和接收HTTP請(qǐng)求與響應(yīng)信息,經(jīng)由Xm lHttpRequest對(duì)象發(fā)送的請(qǐng)求不需要Web頁面存在或返回一個(gè)form表單元素。文件的異步上傳就是通過使用該對(duì)象直接與Web服務(wù)器進(jìn)行通信[5],在頁面不重載或不轉(zhuǎn)向的情況下將文件上傳請(qǐng)求發(fā)送至服務(wù)器并返回處理結(jié)果,進(jìn)而實(shí)現(xiàn)文件異步傳輸。相對(duì)傳統(tǒng)的瀏覽同步提交,文件拖拽的異步傳輸方式既提升了用戶體驗(yàn),又減輕了服務(wù)器負(fù)載,是HTML5環(huán)境下Web應(yīng)用的一種新型技術(shù)形式,也是目前本地文件Web傳輸瓶頸的解決途徑之一,有著較為廣闊的應(yīng)用前景。
1.1 原理
在HTML5以前,要實(shí)現(xiàn)Web對(duì)象的拖放操作不僅需要逐一實(shí)現(xiàn)mouseDown、mouseMove、mouseUp等一系列鼠標(biāo)事件,而且還需要編寫大量JS代碼,編寫完的應(yīng)用程序體積龐大、代碼冗余[6],更為主要的是這些冗余的代碼僅僅能實(shí)現(xiàn)瀏覽器內(nèi)部對(duì)象的相互拖放。HTML5給文件的跨應(yīng)用拖放提供了快速便捷的實(shí)現(xiàn)方式,只需要給被拖放元素添加“draggable=true”屬性值即可,一個(gè)標(biāo)記有該屬性值的元素允許用戶將其拖放至其他位置,同時(shí)也允許用戶將其他對(duì)象拖放至自身區(qū)域內(nèi)部,同時(shí)觸發(fā)相應(yīng)事件,用戶可以從這些觸發(fā)的事件中準(zhǔn)確及時(shí)地獲取元素從拖放開始至放下鼠標(biāo)過程的各種狀態(tài)和數(shù)據(jù)。圖1反映了元素A在被拖放過程各事件響應(yīng)流程。
圖1拖放過程各事件響應(yīng)流程
在具體實(shí)現(xiàn)Web元素的拖放操作時(shí),除了要逐一實(shí)現(xiàn)圖1所示的各種相關(guān)拖放事件外,還要使用prevent-Default()[7]方法通知瀏覽器不要執(zhí)行與事件關(guān)聯(lián)的默認(rèn)動(dòng)作。而很多HTML標(biāo)簽通常會(huì)有一個(gè)默認(rèn)的動(dòng)作,比如:
<a id=“l(fā)ink”href=“http://www.mypido.cn”>百度</a>
默認(rèn)情況下,鼠標(biāo)點(diǎn)擊了這個(gè)鏈接即會(huì)打開百度首頁,若在頁面加入如下JS代碼后就不會(huì)執(zhí)行打開鏈接這個(gè)默認(rèn)動(dòng)作了:
var link1=document.getElementById(“l(fā)ink”);//獲取id為link的元素
link1.onclick=function(e){//單擊link1元素時(shí)觸發(fā)
e.preventDefault();//阻止或取消了link1元素的默認(rèn)動(dòng)作}
現(xiàn)在假定Web頁中有red、blue、yellow三個(gè)div,根據(jù)如下步驟即可實(shí)現(xiàn)將blue拖放至red、yellow任意一個(gè)div中。
Step 1:獲取三個(gè)div
var yellow=document.getElementById(“yellow”);//獲取id為yellow的元素
var blue=document.getElementById(“blue”);//獲取id為blue的元素
var red=document.getElementById(“red”);//獲取id為red的元素
Step 2:設(shè)置手動(dòng)blue時(shí)的數(shù)據(jù)
blue.ondragstart=function(e){//當(dāng)拖動(dòng)開始時(shí)觸發(fā),產(chǎn)生一個(gè)事件對(duì)象e
e.dataTransfer.setData(“blueDiv”,“blue”);//設(shè)置blueDiv的值為blue元素}
dataTransfer是事件對(duì)象的一個(gè)屬性,用于從被拖拽元素向目標(biāo)元素傳遞字符串格式的數(shù)據(jù),有setData()和getData()兩種方法,后者用于獲取前者保存的數(shù)據(jù)。
Step 3:阻止yellow和red兩元素默認(rèn)事件
yellow.ondragover=function(e){//當(dāng)有元素拖動(dòng)至yellow元素上方時(shí)觸發(fā)
e.preventDefault();}red.ondragover=function(e){//當(dāng)有元素拖動(dòng)至red元素上方時(shí)觸發(fā)
e.preventDefault();}
Step 4:目標(biāo)元素接受被拖動(dòng)元素時(shí)
yellow.ondrop=addNewTag;//當(dāng)yellow完全接受被拖動(dòng)元素blue時(shí)觸發(fā)addNewTag
red.ondrop=addNewTag;//當(dāng)red完全接受被拖動(dòng)元素blue時(shí)觸發(fā)addNewTag
function addNewTag(e){
var recDiv=document.getElementById(e.dataTransfer.getData(“blueDiv”));//獲取之前保存的blueDiv數(shù)據(jù)
e.target.appendChild(recDiv);//在當(dāng)前元素內(nèi)部添加新元素recDiv}
1.2 架構(gòu)
HTML5實(shí)現(xiàn)了本地文件的瀏覽器端應(yīng)用,實(shí)現(xiàn)了Web應(yīng)用程序集成的最終目標(biāo)。接下來就需要在瀏覽器端通過JS加載和解析拖放來的文件,然后使用Ajax的XMLHttpRequest對(duì)象將文件異步傳輸至服務(wù)器。圖2描述了多圖片文件異步上傳架構(gòu)。
圖2異步上傳架構(gòu)
在較早以前的Web時(shí)代,Web應(yīng)用中的本地文件訪問功能需要借助flash、silverlight[8]、ActiveX[9]等特定插件技術(shù)才能實(shí)現(xiàn),例如,我們非常熟悉的IE瀏覽器就需要借助ActiveX控件才能訪問本地文件。使用了這些特定技術(shù)的Web應(yīng)用的獨(dú)立性和通用性都較差,而且很難實(shí)現(xiàn)跨平臺(tái)、跨應(yīng)用的統(tǒng)一表現(xiàn)。HTML5的File API提供了一套完整的文件操作標(biāo)準(zhǔn),包括Web應(yīng)用客戶端表現(xiàn)和文件操作對(duì)象的應(yīng)用程序接口,使得基于Web應(yīng)用的文件讀寫任務(wù)變得易為輕松。其中dataTransfer對(duì)象用于傳輸拖拽過程中的文件信息,表1和表2列出了其常用的屬性和方法。
表1 dataTransfer對(duì)象主要方法
表2 dataTransfer對(duì)象主要屬性
在文件拖拽過程中,可以通過dataTransfer對(duì)象來傳輸文件數(shù)量、類型、大小等數(shù)據(jù),以供拖拽操作結(jié)束后對(duì)這些數(shù)據(jù)進(jìn)行判斷、顯示等操作。下面程序以上傳多張本地圖片文件為例詳細(xì)描述了拖放判斷的過程。
var picContainer=document.getElementById(′pic ̄container′);//獲取顯示圖片的容器DIV
picContainer.addEventListener(“drop”,function(e){//給容器添加拖拽結(jié)束后事件監(jiān)聽
e.preventDefault();//取消默認(rèn)行為
var fileList=e.dataTransfer.files;//獲取傳輸?shù)膱D片文件列表
var n=fileList.length;//獲取圖片文件數(shù)量
for(i=0;i<n;i++){//判斷圖片大小及格式
if(fileList[i].size>1024*1000)error+=′第′+(i+1)+′個(gè)圖片體積過大\n′;if(!/image/i.test(fileList[i]. type))error+=′第′+(i+1)+′個(gè)不是圖片格式\n′;}
if(error){//如果有不符合條件的圖片,則顯示錯(cuò)誤信息,并終止程序
alert(error);return false;}
for(i=0;i<n;i++){//顯示拖拽來的圖片
var img=window.webkitURL.createObjectURL(fileList[i]);//創(chuàng)建第i+1個(gè)圖片的url
var str=“<img src=′”+img+“′><p>圖片名稱:”+fileList[i].name+“</p><p>大?。骸保玀ath.floor((fileList[i].size)/1024)+“KB</p>”;}
MYM(“#pic ̄container”).html(str);//將str字符串放置在id為pic ̄container容器內(nèi)
Web應(yīng)用的異步處理是指不向服務(wù)器提交完整頁面的情況下實(shí)現(xiàn)Web頁面數(shù)據(jù)的局部更新和提交。Ajax可以構(gòu)建更為動(dòng)態(tài)和響應(yīng)更靈敏的Web應(yīng)用程序。其中的XMLHttpRequest對(duì)象提供了對(duì)HTTP協(xié)議的完整訪問,包括對(duì)POST和GET請(qǐng)求的訪問能力[5],異步或同步的返回Web服務(wù)器的響應(yīng),它不局限于對(duì)XML的操作,可以接收任何形式的數(shù)據(jù),是基于Ajax的Web應(yīng)用構(gòu)架的核心組件。異步傳輸其實(shí)就相當(dāng)于在客戶端和服務(wù)器之間架設(shè)了一個(gè)中間層,可以把同步傳輸過程中的部分請(qǐng)求負(fù)擔(dān)分?jǐn)偨o客戶端處理,減輕了服務(wù)器的承載壓力,縮短了響應(yīng)時(shí)間,提高了程序的可操作性,增強(qiáng)了界面的友好性與直觀性[10]。
XMLHttpRequest對(duì)象中用于異步傳輸?shù)暮诵姆椒ㄓ衞pen()和send(),分別用于初始化和發(fā)送HTTP參數(shù)和請(qǐng)求。open()方法的具體結(jié)構(gòu)如圖3所示。
圖3 open()方法結(jié)構(gòu)
如果open()方法指定了POST或GET請(qǐng)求方式,send()方法要指定具體的請(qǐng)求體。比如,要以POST方式提交上傳的文件,就需要將文件所在的表單內(nèi)容formData作為請(qǐng)求體,然后再send(formData)。對(duì)于拖拽來的文件,可以通過使用FromData對(duì)象的append()方法將其逐一添加至動(dòng)態(tài)模擬的表單控件中,即formData.append(“files[]”,e.dataTransfer.files[i])。以下程序段將第2章中拖拽來的圖片文件異步上傳至服務(wù)器[11]。
xhr=new XMLHttpRequest();//生成XMLHttpRequest對(duì)象的一個(gè)實(shí)例
xhr.open(“post”,“/upload.php”,true);//以post方式異步打開upload.php文件,該文件存儲(chǔ)于服務(wù)器,用于處理客戶端提交的表單數(shù)據(jù)
var formData=new FormData();//生成FormData對(duì)象的一個(gè)實(shí)例來模擬表單
for(i=0;i<n;i++){//將拖拽來的文件逐一添加至formData中
formData.append(“myfiles[]”,fileList[i]);
}
xhr.send(formData);//發(fā)送表單數(shù)據(jù)
HTML5的拖放技術(shù)不僅實(shí)現(xiàn)了頁面內(nèi)元素的相互拖拽,而且使得本地文件直接拖拽至瀏覽器成為可能。當(dāng)文件拖拽操作結(jié)束時(shí)觸發(fā)目標(biāo)區(qū)域的ondrop事件,進(jìn)而通過使用HTML5的File API中dataTransfer對(duì)象獲取拖拽文件的name/size/type等屬性,并將符合條件的文件顯示在目標(biāo)區(qū)域,同時(shí)逐一將這些文件添加在由FormData生成的模擬表單中,最后由XMLHttpRequest對(duì)象異步上傳到服務(wù)器。相比傳統(tǒng)方法,基于HTML5的拖放技術(shù)具有以下3個(gè)優(yōu)點(diǎn):
(1)Web前端響應(yīng)較快:基于客戶端主機(jī)的判斷驗(yàn)證減少了服務(wù)器驗(yàn)證返回結(jié)果的響應(yīng)過程。
(2)容錯(cuò)能力較強(qiáng):Ajax使用異步交互技術(shù),提高了網(wǎng)頁的連續(xù)性和響應(yīng)速度[12],即使進(jìn)程中斷也不會(huì)導(dǎo)致系統(tǒng)崩潰。
(3)用戶體驗(yàn)較良好:減少了繁瑣的操作過程,提高了傳輸效率,降低了用戶等待時(shí)間。
盡管HTML5新技術(shù)具有較強(qiáng)的移植性和跨平臺(tái)運(yùn)行性,有效提高了程序可用性,但是由于目前瀏覽器技術(shù)的兼容性和支持性不夠完善,再加上缺少一種統(tǒng)一的數(shù)據(jù)描述標(biāo)準(zhǔn),使得這些新技術(shù)還不能較好的共享通用。然而,隨著規(guī)范的逐步完善,HTML5必將成為移動(dòng)互聯(lián)網(wǎng)領(lǐng)域的主宰者,帶來更加豐富的網(wǎng)絡(luò)應(yīng)用。
[1]陶國(guó)榮.HTML5實(shí)戰(zhàn)[M].北京:機(jī)械工業(yè)出版社,2011.
[2]劉華星,楊庚.HTML5下一代Web開發(fā)標(biāo)準(zhǔn)研究[J].計(jì)算機(jī)技術(shù)與發(fā)展,2011,21(8):54-58+62.
[3]童麗霞,何加銘,陳懇,等.基于HTML5技術(shù)的W idget引擎內(nèi)容緩存模型及實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用研究,2011,28(12):4625-4628.
[4]Network Working Group.Hypertext Transfer Protocol-HTTP/1.1[EB/OL].(2004-09-01)[2014-08-16].http:// www.w3.org/Protocols/rfc2616/rfc2616.htm l
[5]呂國(guó)勇,史祥龍.基于嵌入式Linux和A jax技術(shù)的Web異步交互設(shè)計(jì)[J].計(jì)算機(jī)應(yīng)用,2013,33(S1):247-251.
[6]鄒夢(mèng)麗,劉小勇.基于A jax技術(shù)創(chuàng)建的異步方法應(yīng)用研究[J].計(jì)算機(jī)時(shí)代,2014(3):33-35.
[7]劉華煜,黃紹龍.通過HTML5的拖放簡(jiǎn)化網(wǎng)站的文件管理[J].洛陽師范學(xué)院學(xué)報(bào),2014,33(5):72-73.
[8]譚淇.基于WCF服務(wù)框架與Silverligh的Web應(yīng)用研究[J].計(jì)算機(jī)與現(xiàn)代化,2011(1):79-81.
[9]楊丁寧,肖暉,張玉清.基于Fuzzing的ActiveX控件漏洞挖掘技術(shù)研究[J].計(jì)算機(jī)研究與發(fā)展,2012,49(7):1525-1532.
[10]戴維,蔣玉芳.基于A jax技術(shù)實(shí)現(xiàn)Web異步樹的應(yīng)用研究[J].計(jì)算機(jī)與現(xiàn)代化,2011(2):148-149,153.
[11]郭兆良.B/S架構(gòu)Web程序中A jax異步傳輸技術(shù)的應(yīng)用研究[J].電腦與信息技術(shù),2013,21(6):41-43.
[12]屈展,李嬋.JSON在A jax數(shù)據(jù)交換中的應(yīng)用研究[J].西安石油大學(xué)學(xué)報(bào):自然科學(xué)版,2011,26(1):95-98.
Realizing Asynchronous Up loading of Multip le Files by Using HTML5 Drag and Drop Technology
LIU Yaoqin
(Department of Computer Science,Yunyang Teachers'College,Shiyan 442000,China)
In traditionalWeb applications,to realize the trans-browser application of local files not only need to write a lot of redundant code but also can not obtain good user experience.The local file is dragged and dropped to the browser by using the HTML5 drags and drops technology,the file attribution is obtained through the data Transfer object of File API,and then the eligible files are added to the analog form generated by FormData,in the end,the content in the form is submitted to the server by using the XMLHttpRequest of Ajax.Thus the dragging,dropping and the asynchronous uploading of the local files are realized,which extremely increases the user experience and decreases the overloading of the server.Asynchronous uploading of Files based upon the drag and drop technology is a new technological form ofweb application which has a good usage prospect.
HTML5;drag and drop;asynchronous;Ajax;File API
TP311
A
1673-1549(2015)01-0017-05
10.11863/j.suse.2015.01.05
2014-12-05
鄖陽師范高等??茖W(xué)校年重點(diǎn)科研項(xiàng)目(2014A01)
劉耀欽(1980-),男,河南禹州人,講師,碩士,主要從事信息安全及Web應(yīng)用方面的研究,(E-mail)22556099@qq.com
四川輕化工大學(xué)學(xué)報(bào)(自然科學(xué)版)2015年1期