當上傳的文件相對較大時,用戶可能須要等待較長的時間,這個時候前端若是沒有任何提示的話,體驗不是很好,若是有上傳進度提示,就會好不少。而要在上傳過程實時顯示上傳進度,則須要已上傳的大小和文件總大小。html
請求是異步的。由於要實時獲取到上傳的進度,則請求需是異步的,若是是同步的話,會直到請求完成才能獲取到響應。前端
這裏總結的主要是js方面,至於進度條的顯示,有的UI框架,好比semantic
就自帶了進度條的實現,直接使用便可,沒有的話也能夠本身用改變div寬度等方式實現,這裏不贅述。vue
如何獲取到文件的上傳進度?
Javascript的XMLHttpRequest
提供了一個progress
事件,這個事件會返回文件已上傳的大小和總大小,根據這兩個值,就能夠計算上傳進度了,關於這個方法,在《Javascript高級程序設計(第3版)》21章第3節中有敘述,有這本書在手的能夠看一下。下面貼一下代碼。html5
使用Javascript的XMLHttpRequest的progress事件,實現示例代碼爲:jquery
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瞭解詳情。web
jQuery
封裝了xhr
的實現, 也能夠使用jQuery
的ajax
得到上傳進度,示例代碼: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_bar").progress('set progress', percent); $("#J_progress_label").html('已上傳:'+percent+'%'); } 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。數據庫
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_bar").progress('set progress', percent); $("#J_progress_label").html('已上傳:'+percent+'%'); } 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。跨域
另一點,上傳成功後設置重定向到網站某頁面的話,可能會報錯跨域重定向。七牛雲存儲