需求
當上傳的文件相對較大時,用戶可能需要等待較長的時間,這個時候前端如果沒有任何提示的話,體驗不是很好,如果有上傳進度提示,就會好很多。愛掏網 - it200.com而要在上傳過程實時顯示上傳進度,則需要已上傳的大小和文件總大小。愛掏網 - it200.com
前提
-
請求是異步的。愛掏網 - it200.com因為要實時獲取到上傳的進度,則請求需是異步的,如果是同步的話,會直到請求完成才能獲取到響應。愛掏網 - it200.com
實現
這里總結的主要是js方面,至于進度條的顯示,有的UI框架,比如semantic
就自帶了進度條的實現,直接使用即可,沒有的話也可以自己用改變div寬度等方式實現,這里不贅述。愛掏網 - it200.com
如何獲取到文件的上傳進度?
Javascript的XMLHttpRequest
提供了一個progress
事件,這個事件會返回文件已上傳的大小和總大小,根據這兩個值,就可以計算上傳進度了,關于這個方法,在《Javascript高級程序設計(第3版)》21章第3節中有敘述,有這本書在手的可以看一下。愛掏網 - it200.com下面貼一下代碼。愛掏網 - it200.com
XMLHttpRequest:progress事件
使用Javascript的XMLHttpRequest的progress事件,實現示例代碼為:
var formData = new FormData();
formData.append("file", document.getElementById('file').files[0]);
formData.append("token", token_value); // 其他參數按這樣子加入
var xhr = new XMLHttpRequest();
xhr.open('POST', '/uploadurl');
// 上傳完成后的回調函數
xhr.onload = function () {
if (xhr.status === 200) {
console.log('上傳成功');
} else {
console.log('上傳出錯');
}
};
// 獲取上傳進度
xhr.upload.onprogress = function (event) {
if (event.lengthComputable) {
var percent = Math.floor(event.loaded / event.total * 100) ;
// 設置進度顯示
$("#J_upload_progress").progress('set progress', percent);
}
};
xhr.send(formData);
復制代碼
關于FormData和XMLHttpRequest
, 可以搜下W3C了解詳情。愛掏網 - it200.com
jQuery封裝的xhr
jQuery
封裝了xhr
的實現, 也可以使用jQuery
的ajax
獲得上傳進度,示例代碼:
var formData = new FormData();
formData.append("file", document.getElementById('file').files[0]);
formData.append("token", token_value);
$.ajax({
url: "/uploadurl",
type: "POST",
data: formData,
processData: false, // 不要對data參數進行序列化處理,默認為true
contentType: false, // 不要設置Content-Type請求頭,因為文件數據是以 multipart/form-data 來編碼
xhr: function(){
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',function(e) {
if (e.lengthComputable) {
var percent = Math.floor(e.loaded/e.total*100);
if(percent = 100) {
$("#J_progress_label").html('文件上傳完畢,請等待...');
$("#J_progress_label").addClass('success');
}
}
}, false);
}
return myXhr;
},
success: function(res){
// 請求成功
},
error: function(res) {
// 請求失敗
console.log(res);
}
});
復制代碼
關于jQuery ajax的xhr, 具體可查看W3C。愛掏網 - it200.com
vue-resource
var formData = new FormData();
formData.append('token', token_value); // csrf token
formData.append("works", document.getElementById('file').files[0]); // file
var url = $("#R_batch_upload_url").val();
vm.$http.post(url, formData, {
progress: (e) => {
if (e.lengthComputable) {
var percent = Math.floor(e.loaded/e.total*100);
if(percent = 100) {
$("#J_progress_label").html('文件上傳完畢,提交表單中,請等待...');
$("#J_progress_label").addClass('success');
}
}
}
})
.then((res) => {
if(res.ok && res.status === 200) {
window.location.href = window.location.href;
}
}, (res) => {
if(res.status === 400) {
$("#J_progress_label").html('文件格式錯誤,請修改后重試');
$("#J_progress_label").addClass('warning');
console.log(res);
vm.errMsg.show = true;
vm.errMsg.msg = res.body.msg;
vm.canSend = true;
// TODO hide the loader dimmer
$("#J_upload_batch").dimmer("hide");
} else {
$("#J_progress_label").html(res.statusText);
$("#J_progress_label").addClass('warning');
}
});復制代碼
七牛云儲存
有些文件過大,后臺會采取上傳到七牛,再獲取其地址保存到數據庫的方式,這種方式的話,前端可以使用上面兩種方式XMLHttpRequest或jQuery封裝的xhr
實現發送請求及獲取上傳進度,如果需要更復雜的上傳數據處理,也可以考慮使用七牛提供的配套Javascript SDK
實現,若是只需要進度提示的話,并不需要引入七牛JS SDK。愛掏網 - it200.com
另外一點,上傳成功后設置重定向到網站某頁面的話,可能會報錯跨域重定向。愛掏網 - it200.com
相關鏈接
-
阮一峰:文件上傳的漸進式增強
-
jquery xhr upload屬性包裝
-
關于文件上傳的那些事
-
html5上傳進度實現
-
七牛文件上傳303重定向
-
重定向 CORS 跨域請求
-
七牛云存儲-Javascript SDK
原文發布時間為:2024年07月02日
作者:掘金
本文來源:掘金?如需轉載請聯系原作者