好的,處理錯誤是完整流程的關鍵。這非常重要。 我們一樣利用先前建立的 Cookie 機制來傳遞錯誤信號,這個方法同樣優雅且可靠。 狠|核心思路 思路很簡單: * 成功時:Cookie 的值等於我們發送的 Token。 * 失敗時:我們讓 Cookie 的值等於一個約定好的、以 "error:" 開頭的錯誤訊息字串。 前端的輪詢檢查 (setInterval) 不再只是傻傻地等 Token,而是會判斷 Cookie 的值: * 如果是 Token -> 代表成功。 * 如果是 "error:..." 開頭 -> 代表失敗,並把後面的訊息顯示出來。 * 如果一直沒反應 -> 可考慮加上超時機制(進階)。 準|精準步驟與程式碼修改 步驟一:修改 Controller (VB.NET) - 捕捉錯誤並設定錯誤 Cookie 我們需要用 Try...Catch 區塊把您的 Excel 產生邏輯包起來。當 Catch 到任何例外狀況 (Exception) 時,就設定錯誤的 Cookie。 Function ExportExcel(ByVal downloadToken As String) As ActionResult Try ' ... 您原本耗時的 Excel 產生邏輯 ... ' 假設這裡可能會出錯,例如資料庫連線失敗 Dim ms As New MemoryStream() ' ... (您將資料寫入 ms 的程式碼) ... ' 如果成功執行到這裡,設定成功的 Cookie Response.SetCookie(New HttpCookie("downloadToken", downloadToken)) Return File(ms.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Report.xlsx") Catch ex As Exception ' 【關鍵】如果 Try 區塊發生任何錯誤,程式會跳到這裡 ' 1. Log 錯誤 (好習慣,方便後續追查) ' 例如:MyLogger.Error("匯出 Excel 失敗", ex) ' 2. 設定一個帶有錯誤訊息的 Cookie ' 我們用 "error:" 作為前綴,方便前端辨識 ' 使用 Server.UrlEncode 確保錯誤訊息中的特殊字元不會弄壞 Cookie Dim errorMessage = "error:" & Server.UrlEncode(ex.Message) Response.SetCookie(New HttpCookie("downloadToken", errorMessage)) ' 3. 回傳一個 HTTP 錯誤狀態碼,雖然前端主要靠 Cookie 判斷, ' 但這對於開發者在 Network 工具中除錯很有幫助。 Return New HttpStatusCodeResult(500, "Excel Generation Failed") End Try End Function 步驟二:升級前端 JavaScript - 檢查成功與失敗兩種情況 修改您的 setInterval 函式,讓它能分辨成功與失敗的 Cookie 值。 JavaScript (@Section Scripts) // ... getCookie 輔助函式維持不變 ... document.getElementById('export-excel-btn').addEventListener('click', function () { // ... 前半段的 swal 轉圈動畫、產生 token、建立 form 的部分都維持不變 ... swal({ title: "處理中...", text: '<i class="fa-solid fa-spinner fa-spin fa-3x"></i><br><br>正在產生 Excel 檔案,請稍候。', html: true, showConfirmButton: false, allowOutsideClick: false }); var token = new Date().getTime(); var downloadUrl = '@Url.Action("ExportExcel", "您的Controller名稱")'; var form = document.createElement("form"); form.setAttribute("method", "post"); form.setAttribute("action", downloadUrl); //... 建立並附加 tokenInput ... var tokenInput = document.createElement("input"); tokenInput.setAttribute("type", "hidden"); tokenInput.setAttribute("name", "downloadToken"); tokenInput.setAttribute("value", token); form.appendChild(tokenInput); document.body.appendChild(form); form.submit(); document.body.removeChild(form); // 【關鍵】升級輪詢檢查的邏輯 var fileDownloadCheckTimer = window.setInterval(function () { var cookieValue = getCookie("downloadToken"); if (cookieValue) { // 只要 cookie 存在就處理 window.clearInterval(fileDownloadCheckTimer); // 不論成功失敗,都先停止輪詢 document.cookie = "downloadToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; // 清除 cookie if (cookieValue == token) { // ** 情況一:成功 ** // Cookie 的值是我們發送的 token swal("完成!", "Excel 檔案已成功匯出。", "success"); } else if (cookieValue.startsWith("error:")) { // ** 情況二:失敗 ** // Cookie 的值以 "error:" 開頭 var encodedMsg = cookieValue.substring(6); // 取得 "error:" 後面的所有訊息 var errorMsg = decodeURIComponent(encodedMsg); // 解碼還原錯誤訊息 swal({ title: "匯出失敗!", text: errorMsg, type: "error" }); } } }, 1000); }); 快|總結 * 後端:用 Try...Catch 包覆核心邏輯。 * Try 成功執行完畢 -> Response.SetCookie("downloadToken", token) * Catch 到錯誤 -> Response.SetCookie("downloadToken", "error:" + 錯誤訊息) * 前端:setInterval 輪詢檢查 Cookie。 * 發現 Cookie 值等於 token -> 跳成功 swal。 * 發現 Cookie 值以 error: 開頭 -> 解析錯誤訊息,跳失敗 swal。 這個升級讓您的功能更加強大且可靠,能優雅地處理後端發生的任何意外狀況,並清晰地反饋給使用者。
留言
留言分享你的想法!
Pocheng Chiu的沙龍
0會員
16內容數
Pocheng Chiu的沙龍的其他內容
2025/09/24
好的,這個情境非常典型,因為 Return FileResult 會直接將檔案串流 (stream) 回傳給瀏覽器,前端的 JavaScript 無法直接監測到下載的「完成」事件。
這是一個瀏覽器機制的限制,但我們可以用一個非常經典且可靠的技巧來完美解決它。
狠|問題穿透:為何 JS 無法監測?
2025/09/24
好的,這個情境非常典型,因為 Return FileResult 會直接將檔案串流 (stream) 回傳給瀏覽器,前端的 JavaScript 無法直接監測到下載的「完成」事件。
這是一個瀏覽器機制的限制,但我們可以用一個非常經典且可靠的技巧來完美解決它。
狠|問題穿透:為何 JS 無法監測?
2025/09/16
好的,了解了。這個情境非常清晰:「建立」與「讀取」是兩個獨立的步驟。
你既然已經成功建立了檔案,現在要讀取它,那麼 FileMode.Open 就是完全正確的選擇。如果在 File.Open 這一步就拋出 InvalidOperationException,問題點幾乎可以鎖定在資源未被釋放。
核心問
2025/09/16
好的,了解了。這個情境非常清晰:「建立」與「讀取」是兩個獨立的步驟。
你既然已經成功建立了檔案,現在要讀取它,那麼 FileMode.Open 就是完全正確的選擇。如果在 File.Open 這一步就拋出 InvalidOperationException,問題點幾乎可以鎖定在資源未被釋放。
核心問
2025/09/09
好的,這是一個非常常見且重要的優化場景。一個清晰、整齊的 Modal 介面能大大提升使用者體驗。
讓我為你提供一個結構清晰、易於理解且美觀的解決方案。我們將運用 Bootstrap 的網格系統 (Grid System) 和表單元件 (Form Controls) 來達成這個目標。
優化核心思路
2025/09/09
好的,這是一個非常常見且重要的優化場景。一個清晰、整齊的 Modal 介面能大大提升使用者體驗。
讓我為你提供一個結構清晰、易於理解且美觀的解決方案。我們將運用 Bootstrap 的網格系統 (Grid System) 和表單元件 (Form Controls) 來達成這個目標。
優化核心思路
你可能也想看














今天寫文章來學習什麼是「第一方 Cookies」。
## 1. Cookie在LinkedIn廣告中的角色
根據Linkedin的文章[1],
Cookie 是被設置在網站訪問者的 Web瀏覽器上,
可以幫助 Linkedin 確定廣告被展示給哪些成員,
是衡量廣告效果,改

今天寫文章來學習什麼是「第一方 Cookies」。
## 1. Cookie在LinkedIn廣告中的角色
根據Linkedin的文章[1],
Cookie 是被設置在網站訪問者的 Web瀏覽器上,
可以幫助 Linkedin 確定廣告被展示給哪些成員,
是衡量廣告效果,改

本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。

本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。

本章節的目的是介紹在TypeScript中如何進行例外處理。涵蓋了例外處理的重要性、語法、常見異常類型以及如何主動觸發異常訊息及用戶自定義異常訊息。為讀者提供了全面而深入的了解,以提高程式的可靠性、提供更好的反饋、增加程式的容錯性以及改善程式的可讀性。

本章節的目的是介紹在TypeScript中如何進行例外處理。涵蓋了例外處理的重要性、語法、常見異常類型以及如何主動觸發異常訊息及用戶自定義異常訊息。為讀者提供了全面而深入的了解,以提高程式的可靠性、提供更好的反饋、增加程式的容錯性以及改善程式的可讀性。

當你在開發程式時,難免會遇到各種錯誤和異常情況。這些錯誤可能是因為代碼中的錯誤、外部資源無法訪問或其他不可預期的狀況。為了提高程式的可靠性、穩定性和可維護性,我們使用「例外處理」來處理這些異常情況。

當你在開發程式時,難免會遇到各種錯誤和異常情況。這些錯誤可能是因為代碼中的錯誤、外部資源無法訪問或其他不可預期的狀況。為了提高程式的可靠性、穩定性和可維護性,我們使用「例外處理」來處理這些異常情況。

公告佈達看似簡單,但如何做好才是關鍵。
只有透過適時而有效的公告,才能確保重要訊息的及時傳達,促進員工的共識和配合
最終提升整體的運營效率,為企業持續發展注入動力!

公告佈達看似簡單,但如何做好才是關鍵。
只有透過適時而有效的公告,才能確保重要訊息的及時傳達,促進員工的共識和配合
最終提升整體的運營效率,為企業持續發展注入動力!

在瀏覽器環境中有許多的儲存空間,想要查看這些空間的話,可以透過「chrome > Dev Tools > Application > Storage」即能進行查看。
瀏覽器內存空間的差異不僅常常被拿來被當作面試考題,在實務開發中更扮演舉足輕重的角色,今天就想透過這系列的文章深度了解這些瀏覽器內存⋯

在瀏覽器環境中有許多的儲存空間,想要查看這些空間的話,可以透過「chrome > Dev Tools > Application > Storage」即能進行查看。
瀏覽器內存空間的差異不僅常常被拿來被當作面試考題,在實務開發中更扮演舉足輕重的角色,今天就想透過這系列的文章深度了解這些瀏覽器內存⋯

👨💻簡介
最近因為憑證越來越多,需要監控什麼時候到期,當到期時發送到期通知,因此撰寫一個簡單的小程式來完成。
這次使用Python和Telegram Bot來監控SSL證書的到期時間並發送通知。並使用GCP工具,如CloudFunction和CloudScheduler做部署平台。

👨💻簡介
最近因為憑證越來越多,需要監控什麼時候到期,當到期時發送到期通知,因此撰寫一個簡單的小程式來完成。
這次使用Python和Telegram Bot來監控SSL證書的到期時間並發送通知。並使用GCP工具,如CloudFunction和CloudScheduler做部署平台。