iT邦幫忙

0

利用前端結合 Ajax 送出表單 並用res.download 回傳下載, 並載入BlockUI

各位前輩好!
我最近用 Express 架了一個server 讓使用者上傳檔案, 並且將檔案轉換變其他內容,然後用response.download直接下載.
一開始我用的是HTML 表格 的 Submit function. 他可以正常下載
但我希望能在使用者等待轉換時,透過blockUI 把畫面鎖住, 等res.download 回打檔案回來時再解開,並且換到別的頁面. 所以我改用Ajax去打
我用postman 測過 依然有回傳資料,但他就是沒有跳出下載畫面.
想請問各位 這個原因是什麼 還有怎麼解決比較好呢? 非常感謝!!!
https://ithelp.ithome.com.tw/upload/images/20181121/20113536NxmnIQE3Eo.pnghttps://ithelp.ithome.com.tw/upload/images/20181121/20113536hNuh62s2sU.png

1 個回答

1
DanSnow
iT邦新手 5 級 ‧ 2018-11-22 10:03:33
最佳解答

若你是用 ajax 去送你那個會下載檔案的 API 的話檔案是由你的 ajax 下載回來的,瀏覽器自然也不會跳出檔案下載。

你如果想透過 ajax 下載檔案的話可以用底下這個做法:

$.ajax({
  url: "https://robohash.org/foo.png",
  xhrFields: {
    // 將回傳結果以 Blob ,也就是保持原本二進位的格式回傳
    responseType: "blob"
  }
}).done((data) => {
  // 這邊一定要用原生的 document.createElement
  // jQuery 沒辦法真的模擬原生的 click event
  const $a = document.createElement("a")
  // 給下載回來的資料產生一個網址
  const url = URL.createObjectURL(data)
  // 設定下載的檔名
  $a.download = "foo.png"
  // 設定網址
  $a.href = url
  // 模擬使用者按下連結
  $a.click()
  // 5 秒後清除產生的網址,這時候使用者應該按下了下載的按鈕了
  // 不清除的話會造成記憶體的浪費,這不會中斷使用者的下載
  // 不過若你下載完就要跳轉到下一頁的話,其實這個可以不用
  setTimeout(() => URL.revokeObjectURL(url), 5000)
})

非常感謝你的回應, 這也是我現在正在嘗試的做法.

但我遇到一些問題,檔名的部分 我想直接從
getResponseHeader裡的 Content-Disposition 的filename
取出來用,
可是我console.log(xhr.getResponseHeader('Content-Disposition'))
得到的結果是null
https://ithelp.ithome.com.tw/upload/images/20181122/20113536j9Xi5b4Db0.png
但我在後端 已經有設定,想請問是我設定的方式有問題嗎?
感謝!
https://ithelp.ithome.com.tw/upload/images/20181122/201135365XYqkVarmX.png

DanSnow iT邦新手 5 級 ‧ 2018-11-22 22:35:45 檢舉

Content-Disposition 的格式是像 Content-Disposition: attachment; filename="filename.jpg" ,你設定的時候把它分成兩段了…,然後我剛剛查了一下文件, res.download 的第二個參數是設定 Content-Disposition 中的檔名,所以你不需要自己設定 header ,可以用那個參數就好

謝謝你,是我設定的時候設定錯誤 非常感謝你的耐心回答!

我要發表回答

立即登入回答