最近在作數據統計功能,需求是導出大數據量的excel,時間間隔較長,大概須要十秒左右,點擊導出後,頁面沒有作任何處理,用戶也不知道是否正在導出;若是沒有作交互上的限制,用戶能夠一直點擊導出按鈕,這樣勢必會形成服務器癱瘓。前端
花了一天嘗試了兩種方案:ajax
單純的前端是沒法監聽文件是否下載完成的,主要試了兩種方案:json
1.因爲導出是用form表單提交的,並將form的target設置到一個隱藏iframe來達到不刷新頁面而導出。原本想利用隱藏iframe的onload事件來判斷是否導出成功的,可是調試發現導出成功後不會觸發,因此該條路沒法走通了。後端
2.用ajax來作導出,可是該方法沒法實現自動下載導出文件,這條路也就沒法走通了。瀏覽器
原本想監聽瀏覽器點擊下載連接到彈出窗口完成的狀態,查閱資料發現這些都是瀏覽器包辦了的,沒有任何方法能夠獲取到狀態,可能瀏覽器是出於安全考慮,因此沒有提供。安全
主體思路是這樣:服務器
前端點擊導出按鈕加載事件並添加遮罩效果,設置定時器監聽ajax從後端返回是否導出完成狀態,後端狀態設置初始session狀態值,在導出事件後改變該session值,最後經過ajax返回前端。前端接收到狀態值,若是已導出完成,解除遮罩;如不是,則繼續定時監聽直到返回導出完成爲止。session
該方案可行。ide
前端js代碼:oop
//點擊導出事件 function startexport(){ $("#divload").show();//打開加載中遮罩 listenEnd(); } function listenEnd() {//定時監聽 var loop = setInterval(function() { if ($("#txtendflag").val() == "1") { clearInterval(loop);//中止定時任務 $("#divload").hide();//關閉加載中遮罩 } else { getendflag(); } }, 1000);//單位毫秒 注意:若是導出頁面很慢時,建議循環時間段稍長一點 } function getendflag() {//請求session標記位 $.ajax({ type : 'post', url : 'ajcxtjlistaction.action?cmd=getendflag', dataType : 'json', success : function(data) { $("#txtendflag").val(data.custom.flag); }, error : function(error) { console.log('接口不通' + error); } }) }
後端Java代碼:
public void export() { request.getSession().removeAttribute("endflag");//每次導入前,清除結束標記 /******該出爲導出代碼******/ /******導出結束*******/ request.getSession().setAttribute("endflag", "1");//設置結束標記 } //獲取結束標記 public Object getendflag() { Object flag = request.getSession().getAttribute("endflag"); //獲取結束標記*/ JSONObject obj = new JSONObject(); obj.put("flag", flag);//返回狀態值 return obj; }