基于Ajax技術實現(xiàn)文件上傳帶進度條
1.概述
在實際的Web應該開發(fā)或網(wǎng)站開發(fā)過程中,經(jīng)常需要實現(xiàn)文件上傳的功能。在文件上傳過程中,經(jīng)常需要用戶進行長時間的等待,為了讓用戶及時了解上傳進度,可以在上傳文件的同時,顯示文件的上傳進度條。運行本實例,如圖1所示,訪問文件上傳頁面,單擊“瀏覽”按鈕選擇要上傳的文件,注意文件不能超過50MB,否則系統(tǒng)將給出錯誤提示。選擇完要上傳的文件后,單擊“提交”按鈕,將會上傳文件并顯示上傳進度。
2.技術要點
主要是應用開源的Common-FileUpload組件來實現(xiàn)分段文件上傳,從而實現(xiàn)在上傳過程中,不斷獲取上傳進度。下面對Common-FileUpload組件進行詳細介紹。
Common-FileUpload組件時Apache組織下的jakarta-commons項目下的一個子項目,該組件可以方便地將multipart/form-data類型請求中的各種表單域解析出來。該組件需要另一個名為Common-IO的組件的支持。這兩個組件包文件可以到http://commons.apache.org網(wǎng)站上進行下載。
(1)創(chuàng)建上傳對象
在應該Common-FileUpload組件實現(xiàn)文件上傳時,需要創(chuàng)建一個工廠對象,并根據(jù)該工廠對象創(chuàng)建一個新的文件上傳對象,具體代碼如下:
DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory);
(2)解析上傳請求
創(chuàng)建一個文件上傳對象后,就可以應用該對象來解析上傳請求,獲取全部的表單項,可以通過文件上傳對象的parseRequest()方法來實現(xiàn)。parseRequest()方法的語法結(jié)構(gòu)如下:
public List parseRequest(HttpServletRequest request) throws FileUploadException
(3)FileItem類
在Common-FileUpload組件中,無論是文件域還是普通表單域,都當成FileItem對象來處理。如果該對象的isFormField()方法返回值為true,則表示是一個普通表單域,否則為一個文件域。在實現(xiàn)文件上傳時,可以通過FileItem類的getName()方法獲得上傳文件的文件名,通過getSize()方法獲得上傳文件的大小。
3.具體實現(xiàn)
(1)創(chuàng)建request.js文件,在該文件中編寫Ajax請求方法。
(2)新建文件上傳頁index.jsp,在該頁中添加用于獲得上傳文件信息的表單以及表單元素,并添加用于顯示進度條的<div>標簽和顯示百分比的<span>標簽,關鍵代碼如下:
<form enctype="multipart/form-data" method="post" action="UpLoad?action=uploadFile">
請選擇上傳的文件:<input name="file" type="file" size="34">
注:文件大小請控制在50M以內(nèi)。
<div id="progressBar" class="prog_border" align="left"> <img src="images/progressBar.gif" width="0" height="13" id="imgProgress"></div> <span id="progressPercent" style="width:40px;display:none">0%</span> <input name="Submit" type="button" value="提交" onClick="deal(this.form)"> <input name="Reset" type="reset" class="btn_grey" value="重置"></td> </form>
(3)新建上傳文件的Servlet實現(xiàn)類UpLpad。在該類中編寫實現(xiàn)文件上傳的方法uploadFile(),在該方法中通過Common-FileUpload組件實現(xiàn)分段上傳文件,并計算上傳百分比,實時保存到Session中,關鍵代碼如下:
public void uploadFile(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=GBK"); request.setCharacterEncoding("GBK"); HttpSession session=request.getSession(); session.setAttribute("progressBar",0); //定義指定上傳進度的Session變量 String error = ""; int maxSize=50*1024*1024; //單個上傳文件大小的上限 DiskFileItemFactory factory = new DiskFileItemFactory(); //創(chuàng)建工廠對象 ServletFileUpload upload = new ServletFileUpload(factory); //創(chuàng)建一個新的文件上傳對象 try { List items = upload.parseRequest(request); // 解析上傳請求 Iterator itr = items.iterator(); // 枚舉方法 while (itr.hasNext()) { FileItem item = (FileItem) itr.next(); //獲取FileItem對象 if (!item.isFormField()) { // 判斷是否為文件域 if (item.getName() != null && !item.getName().equals("")) {//是否選擇了文件 long upFileSize=item.getSize(); //上傳文件的大小 String fileName=item.getName(); //獲取文件名 if(upFileSize>maxSize){ error="您上傳的文件太大,請選擇不超過50M的文件"; break; } // 此時文件暫存在服務器的內(nèi)存中 File tempFile = new File(fileName); //構(gòu)造文件目錄臨時對象 String uploadPath = this.getServletContext().getRealPath("/upload"); File file = new File(uploadPath,tempFile.getName()); InputStream is=item.getInputStream(); int buffer=1024; //定義緩沖區(qū)的大小 int length=0; byte[] b=new byte[buffer]; double percent=0; FileOutputStream fos=new FileOutputStream(file); while((length=is.read(b))!=-1){ percent+=length/(double)upFileSize*100D; //計算上傳文件的百分比 fos.write(b,0,length); //向文件輸出流寫讀取的數(shù)據(jù) session.setAttribute("progressBar",Math.round(percent)); } fos.close(); Thread.sleep(1000); //線程休眠1秒 } else { error="沒有選擇上傳文件!"; } } } } catch (Exception e) { e.printStackTrace(); error = "上傳文件出現(xiàn)錯誤:" + e.getMessage(); } if (!"".equals(error)) { request.setAttribute("error", error); request.getRequestDispatcher("error.jsp").forward(request, response); }else { request.setAttribute("result", "文件上傳成功!"); request.getRequestDispatcher("upFile_deal.jsp").forward(request, response); } }
(4)在文件上傳頁index.jsp中,導入編寫的Ajax請求方法的request.js文件,并編寫獲取上傳進度的Ajax請求方法和Ajax回調(diào)函數(shù),關鍵代碼如下:
<script language="javascript" src="js/request.js"></script> <script language="javascript"> var request = false; function getProgress(){ var url="showProgress.jsp"; //服務器地址 var param ="nocache="+new Date().getTime(); //每次請求URL參數(shù)都不同 ,避免上傳時進度條不動 request=httpRequest("post",url,true,callbackFunc,param); //調(diào)用請求方法 } //Ajax回調(diào)函數(shù) function callbackFunc(){ if( request.readyState==4 ){ //判斷響應是否完成 if( request.status == 200 ){ //判斷響應是否成功 var h = request.responseText; //獲得返回的響應數(shù)據(jù),該數(shù)據(jù)位上傳進度百分比 h=h.replace(/\s/g,""); //去除字符串中的Unicode空白符 document.getElementById("progressPercent").style.display=""; //顯示百分比 progressPercent.innerHTML=h+"%"; //顯示完成的百分比 document.getElementById("progressBar").style.display="block"; //顯示進度條 document.getElementById("imgProgress").width=h*(235/100); //顯示完成的進度 } } } </script>
(5)編寫showProgress.jsp頁面,在該頁中應用EL表達式輸出保存在session域中的上傳進度條的值,具體代碼如下:
<%@page contentType="text/html" pageEncoding="GBK"%> ${progressBar}
(6)編寫表單提交按鈕onclick事件所調(diào)用的JavaScript方法,在該方法通過window對象的setInterval()方法每隔一定時間請求一次服務器,獲得最新的上傳進度,關鍵代碼如下:
function deal(form){ form.submit(); //提交表單 timer=window.setInterval("getProgress()",500); //每隔500毫秒獲取一次上傳進度 }
以上所述是小編給大家介紹的基于Ajax技術實現(xiàn)文件上傳帶進度條的相關知識,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
原生ajax和iframe框架實現(xiàn)圖片文件上傳的兩種方式
這篇文章主要為大家詳細介紹了原生ajax和iframe框架實現(xiàn)圖片文件上傳的兩種方式,感興趣的小伙伴們可以參考一下2016-04-04Ajax讀取數(shù)據(jù)之分頁顯示篇實現(xiàn)代碼
前幾篇的ajax教程里講了,讀取,添加,修改,刪除的功能.有幾天沒有更新了,雖然網(wǎng)上也有很多ajax分頁的教程和相關實例.2010-10-10淺析json與jsonp區(qū)別及通過ajax獲得json數(shù)據(jù)后格式的轉(zhuǎn)換
一言以蔽之,json返回的是一串數(shù)據(jù);而jsonp返回的是腳本代碼(包含一個函數(shù)調(diào)用);接下來通過本文給大家介紹json與jsonp區(qū)別及通過ajax獲得json數(shù)據(jù)后格式的轉(zhuǎn)換,需要的朋友參考下2016-03-03你的jquery ajax無效和你的jquery引入路徑有關
當你發(fā)現(xiàn)你的jquery ajax無效的時候,不妨使用 fire bug調(diào)試一下,這時你會發(fā)現(xiàn),提示"$"無效,為什么會有這種提示呢?可能是你引入jquery.js的路徑有問題2013-06-06實現(xiàn)AJAX異步調(diào)用和局部刷新的基本步驟
AJAX?可以在不重新加載整個網(wǎng)頁的情況下,與服務器交換數(shù)據(jù),并且更新部分網(wǎng)頁,下面這篇文章主要給大家介紹了關于實現(xiàn)AJAX異步調(diào)用和局部刷新的基本步驟,需要的朋友可以參考下2022-03-03