首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Servlet 檔案下載瀏覽器無反應:AJAX 請求導致

     編輯:程式設計綜合問答

現象

Servlet 使用 `response.getOutputStream()` 輸出檔案,設定 `Content-Disposition: attachment`,但瀏覽器不彈出「另存新檔」對話框,無任何反應。

根本原因

前端使用 **AJAX (XMLHttpRequest / fetch / jQuery.ajax)** 發起下載請求。AJAX 請求的回應**僅在 JavaScript 可用**,瀏覽器**不會**自動處理 `Content-Disposition: attachment` 彈出下載對話框。

解決方案

  1. 改用普通導航請求(推薦):
    // 前端
    window.location.href = '/downloadServlet?fileId=123'; // 或
    // 下載
  2. 若必須用 AJAX(如需驗證權限再下載):
    // 1. AJAX 請求驗證,成功後回傳下載 Token 或簽名 URL
    // 2. 前端拿到 Token 後
    window.location.href = '/downloadServlet?token=' + token; // 觸發瀏覽器下載
    
    // 或使用 Blob + Object URL(現代瀏覽器)
    fetch('/downloadServlet?fileId=123', {credentials: 'include'})
      .then(res => res.blob())
      .then(blob => {
          const url = URL.createObjectURL(blob);
          const a = document.createElement('a');
          a.href = url;
          a.download = 'filename.zip'; // 從 response headers 解析或指定
          a.click();
          URL.revokeObjectURL(url);
      });

Servlet 端關鍵 Header

response.setContentType("application/octet-stream"); // 通用二進位
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setContentLengthLong(file.length()); // 支援大檔案
// 輸出流寫入...

常見坑

  • 對中文檔名未 `URLEncoder.encode` → 瀏覽器顯示亂碼或截斷。
  • 未設定 `Content-Length` → 進度條無法顯示、大檔案可能中斷。
  • 在 `try-with-resources` 中關閉 `ServletOutputStream` 過早 → 連結中斷。

結論

檔案下載**必須**由瀏覽器主導導航請求(``、`window.location`、`form submit`)觸發,AJAX 無法直接啟動瀏覽器下載 UI。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved