這回在實務上遇上:讓使用者在點「下載」按鈕後,就幫使用者自動下載到本機端。這邊筆記下可能會用到的常用類型方法,以及要注意的事項。
說明
PDF, Microsoft Office 系列檔案
若是一般的文件系列檔案,這在 HTML5 的預設行為中是可以直接被下載下來的,所以你僅需要在使用者點選按鈕後,幫使用者建立一個 <a> 標籤、加上 download 和 href 的內容,再幫使用者點選即可
圖片和 txt 文字檔
由於瀏覽器預設是會「另開視窗」打開這兩個檔案,並不會自動幫你下載到本機端。因此,你需要先行將圖片和文字先取到本機端後,產生一個 local 端地暫存。接著用幫使用者點下這個暫存檔的所在連結。
注意事項
需要注意 CORS 的問題。若後端伺服器並沒有回傳對應的 Response Header,那就有機會被瀏覽器給拒絕而無法下載。
程式碼
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Auto Download File and Save Demo</title> | |
</head> | |
<body> | |
<div class="buttons" style="display:flex; flex-wrap:nowrap"> | |
<button id="download-btn-image" style="margin:0 8px;"> | |
Download Image | |
</button> | |
<button id="download-btn-pdf" style="margin:0 8px;"> | |
Download PDF | |
</button> | |
<button id="download-btn-xlsx" style="margin:0 8px;"> | |
Download Spreadsheet (.xlsx) | |
</button> | |
<button id="download-btn-doc" style="margin:0 8px;"> | |
Download Word File | |
</button> | |
<button id="download-btn-txt" style="margin:0 8px;"> | |
Download Txt | |
</button> | |
<button id="download-btn-ppt" style="margin:0 8px;"> | |
Download PowerPoint | |
</button> | |
</div> | |
<script src="./auto-download-file-and-save-demo.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const demoTypeList = [ | |
{ type: 'image', url: 'https://upload.wikimedia.org/wikipedia/commons/5/57/Binance_Logo.png' }, | |
{ type: 'pdf', url: 'https://abseil.io/resources/swe_at_google.2.pdf' }, | |
{ type: 'xlsx', url: 'https://www.google.com/help/hc/downloads/sa360/Location-Language-Codes-GoogleAds.xlsx' }, | |
{ type: 'doc', url: 'https://www-03.ibm.com/software/sla/sladb.nsf/8bd55c6b9fa8039c86256c6800578854/6fb5af3e1e25830e8525843200220908/$FILE/i126-8560-01_07-2019_zh_TW.docx' }, | |
{ type: 'txt', url: 'https://www.easy168.tw/urllist.txt' }, | |
{ type: 'ppt', url: 'https://sysh.tc.edu.tw/var/file/64/1064/img/545856627.ppt' } | |
] | |
demoTypeList.forEach(item => { | |
initBtnDownload(item) | |
}) | |
function initBtnDownload(item){ | |
switch (item.type){ | |
case 'txt': | |
document.querySelector(`#download-btn-${item.type}`) | |
.addEventListener('click', async function (event) { | |
try { | |
const txtRaw = await (await fetch(item.url)).text() | |
const txtBlob = new Blob([txtRaw], { type: "text/plain;charset=utf-8" }) | |
const txtURL = URL.createObjectURL(txtBlob) | |
const aLinkDOM = document.createElement('a') | |
aLinkDOM.href = txtURL | |
aLinkDOM.download = 'demo.txt' | |
document.body.appendChild(aLinkDOM) | |
aLinkDOM.click() | |
document.body.appendChild(aLinkDOM) | |
} catch (err) { | |
console.log(err) | |
} | |
}) | |
break | |
case 'image': | |
document.querySelector(`#download-btn-${item.type}`) | |
.addEventListener('click', async function (event) { | |
try { | |
const image = await fetch(item.url) | |
const imageBlob = await image.blob() | |
const imageURL = URL.createObjectURL(imageBlob) | |
const aLinkDOM = document.createElement('a') | |
aLinkDOM.href = imageURL | |
aLinkDOM.download = '' | |
document.body.appendChild(aLinkDOM); | |
aLinkDOM.click() | |
document.body.removeChild(aLinkDOM); | |
URL.revokeObjectURL(imageURL) | |
} catch (err) { | |
console.log(err) | |
} | |
}) | |
break | |
default: | |
document.querySelector(`#download-btn-${item.type}`).addEventListener('click', function (event) { | |
const aLinkDom = document.createElement('a') | |
aLinkDom.href = item.url | |
aLinkDom.download = '' | |
document.body.appendChild(aLinkDom); | |
aLinkDom.click() | |
document.body.removeChild(aLinkDom); | |
}) | |
break | |
} | |
} |