[JS筆記]解決html<a href=”” download=””>無法直接下載檔案至本機問題

Kim.H
4 min readMar 29, 2023

--

在實作短網址產生器的練習時,除了產生短網址及QR code之外,還想要新增一個功能,按下按鈕後可以把產生的QR code圖檔直接下載至本機中,因此google尋找可解決的方式。

*產生QR code可參考我的另一篇文章

首先在MDN看到了可以在<a>元素中新增一個download屬性,即可將URL視為下載,在w3schools中也有提到:

The optional value of the download attribute will be the new name of the file after it is downloaded.

download後面接的值會變成下載檔案的檔名,因此我在HTML中這樣寫(此處有套用bootstrap):

 <a
href="https://chart.googleapis.com/chart?cht=qr&chl=https://google.com&chs=150x150"
class="btn btn-outline-primary mb-2"
download="qr-code.png"
>Download</a>

結果點下按鈕之後,會直接開啟一個新連結並顯示QR code圖片,不會直接下載到本機中。

點擊後另起新視窗顯示圖片

這並不是我想要達到的效果,後來發現在MDN文件中有提到:

download僅適用於同源 URLblob:anddata:方案。

瀏覽器顧及安全性問題,僅支持同源下載的連結,也就是URL須是相同的網域、主機名稱和埠號才能夠下載至本機。

那該怎麼做才能達成將QR code圖檔直接下載至本機的目的呢?

再次透過強大的Google查詢替代方案,發現MDN文件中其實有提到可以透過Canvas畫布來下載圖檔

Using the download attribute to save a <canvas> as a PNG

If you want to let users download an HTML <canvas> element as an image, you can create a link with a download attribute and the canvas data as a file URL:

不囉嗦,直接來看程式碼:

HTML:

<img src="https://chart.googleapis.com/chart?cht=qr&chl=https://google.com&chs=150x150" alt="" id="qr-code" />
<button
type="button"
class="btn btn-outline-primary mb-2"
onclick="downloadQRCode()" <!-- 加入onclick後面接js function -->
>Download</button>

JavaScript:

function downloadQRCode() {
const qrCodeImage = document.getElementById("qr-code");
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
const img = document.createElement("img");
//當圖像加載完成時,onload事件將被觸發
img.onload = () => {
//使用canvas元素來繪製QR code
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0);
const url = canvas.toDataURL(); //將圖像轉換為DataURL格式
const a = document.createElement("a"); //創立新的a元素並設定其屬性
a.href = url;
a.download = "QR-Code.png";
a.click(); //模擬click事件, 將會下載圖片至本機中
};
img.crossOrigin = "anonymous"; //防止跨域請求被阻止
img.src = qrCodeImage.src;
}

透過canvas重製QR code,並將其轉換成DataURL格式當作新的元素<a>中href屬性的連結,這樣以來就可以解決瀏覽器非同源導致不能下載的問題啦!

--

--

Kim.H

現任菜鳥後端工程師 / 2022.12 正式踏入轉職之旅 - 2023.09轉職成功