首頁 > web前端 > js教程 > 主體

基於Ajax技術實作檔案上傳帶進度條

亚连
發布: 2018-05-23 17:00:29
原創
1420 人瀏覽過

這篇文章主要介紹了基於Ajax技術實現文件上傳帶進度條的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

1.概述

在實際的Web應該開發或網站開發過程中,經常需要實作文件上傳的功能。在文件上傳過程中,經常需要用戶進行長時間的等待,為了讓用戶及時了解上傳進度,可以在上傳文件的同時,顯示文件的上傳進度條。執行本實例,如圖1所示,造訪文件上傳頁面,點選「瀏覽」按鈕選擇要上傳的文件,注意文件不能超過50MB,否則系統將給予錯誤提示。選擇完要上傳的檔案後,按一下「提交」按鈕,將會上傳檔案並顯示上傳進度。

2.技術要點

#主要是套用開源的Common-FileUpload元件來實作分段檔案上傳,從而實現在上傳過程中,不斷取得上傳進度。以下對Common-FileUpload元件進行詳細介紹。

Common-FileUpload元件時Apache組織下的jakarta-commons項目下的子項目,該元件可以方便地將multipart/form-data類型請求中的各種表單域解析出來。該元件需要另一個名為Common-IO的元件的支援。這兩個元件包檔案可以到http://commons.apache.org網站下載。

(1)建立上傳對象

在應該Common-FileUpload元件實作檔案上傳時,需要建立一個工廠對象,並根據該工廠對象建立一個新的文件上傳對象,具體程式碼如下:

DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
登入後複製

(2)解析上傳請求

建立一個檔案上傳物件後,就可以套用該物件來解析上傳請求,取得全部的表單項,可以透過檔案上傳物件的parseRequest()方法來實現。 parseRequest()方法的語法結構如下:

public List parseRequest(HttpServletRequest request) throws FileUploadException
登入後複製

(3)FileItem類別

在Common-FileUpload元件中,無論是檔案域或普通表單域,都當成FileItem物件來處理。如果該物件的isFormField()方法傳回值為true,則表示為普通表單域,否則為一個檔案域。在實作檔案上傳時,可以透過FileItem類別的getName()方法來取得上傳檔案的檔案名,透過getSize()方法取得上傳檔案的大小。

3.具體實作

#(1)建立request.js文件,在該文件中編寫Ajax請求方法。

(2)新檔案上傳頁index.jsp,在該頁中新增用於取得上傳檔案資訊的表單以及表單元素,並新增用於顯示進度列的

標籤和顯示百分比的標籤,關鍵程式碼如下:

<form enctype="multipart/form-data" method="post" action="UpLoad?action=uploadFile">
登入後複製

請選擇上傳的檔案:

註:檔案大小請控制在50M以內。

<p id="progressBar" class="prog_border" align="left">
<img src="images/progressBar.gif" width="0" height="13" id="imgProgress"></p>
<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實作類別UpLpad。在該類別中編寫實作檔案上傳的方法uploadFile(),在該方法中透過Common-FileUpload元件實作分段上傳文件,並計算上傳百分比,即時儲存到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(); //创建工厂对象
ServletFileUpload upload = new ServletFileUpload(factory); //创建一个新的文件上传对象
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;
}
// 此时文件暂存在服务器的内存中
File tempFile = new File(fileName); //构造文件目录临时对象
String uploadPath = this.getServletContext().getRealPath("/upload");
File file = new File(uploadPath,tempFile.getName()); 
InputStream is=item.getInputStream();
int buffer=1024; //定义缓冲区的大小
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); //向文件输出流写读取的数据
session.setAttribute("progressBar",Math.round(percent)); 
}
fos.close();
Thread.sleep(1000); //线程休眠1秒
} else {
error="没有选择上传文件!";
}
}
}
} catch (Exception e) {
e.printStackTrace();
error = "上传文件出现错误:" + 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回呼函數,關鍵程式碼如下:

<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参数都不同 ,避免上传时进度条不动
request=httpRequest("post",url,true,callbackFunc,param); //调用请求方法 
}
//Ajax回调函数
function callbackFunc(){
if( request.readyState==4 ){ //判断响应是否完成 
if( request.status == 200 ){ //判断响应是否成功
var h = request.responseText; //获得返回的响应数据,该数据位上传进度百分比
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事件所呼叫的JavaScript方法,在該方法透過window物件的setInterval()方法每隔一定時間請求一次伺服器,取得最新的上傳進度,關鍵程式碼如下:

function deal(form){
form.submit(); //提交表单
timer=window.setInterval("getProgress()",500); //每隔500毫秒获取一次上传进度
}
登入後複製

上面是我整理給大家的,希望未來會對大家有幫助。

相關文章:

探討Ajax中有關readyState和status的問題

全面解析$.Ajax()方法參數(圖文教學)

IE8下Ajax快取問題及解決方法

##

以上是基於Ajax技術實作檔案上傳帶進度條的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板