JSで画像をダウンロードするのに色々調べたので備忘録です。
間違った点などあればご教授いただければ幸いです。
尚、こちらはChrome、Firefox、IE11で動作確認してます。
※Safariについては未検証です。
#download属性を使えばできるらしい
下記のように、aタグにdownload属性を付与して記述すれば
ファイルをダウンロードさせることが出来ます。
<a href="/path/img/file.png" download="file.png">Image Download</a>
これだけで、画像がダウンロードできるようになります。
めっちゃ簡単。
#ブラウザの対応
しかし、download属性のブラウザ実装状況 を見ると、、、
Internet Explorer : なし
でた。IE。
本当に嫌いです。
実際にやってみると、IEではダウンロードが実行されず
そのままページ遷移して画像が表示されてしまいました…。
#どうやったらIEでも動くようになるのか
どうやら、navigatorオブジェクトに用意されている
msSaveBlob(blob, fileName)
または msSaveOrOpenBlob(blob, fileName)
というメソッドを使えばいいらしいです。
※この2つの違いについては、こちら で詳しく説明されているので参考までにどうぞ。
実際にやってみると
<a onclick="downloadImg();">画像ダウンロード</a>
function downloadImg () {
const fileName = 'file.png';
const uri = '/path/img/file.png';
let xhr = new XMLHttpRequest();
xhr.open('GET', uri);
xhr.responseType = 'blob';
xhr.onloadend = () => {
if (xhr.status !== 200) {
return false;
}
window.navigator.msSaveOrOpenBlob(xhr.response, fileName);
};
xhr.send();
}
こんな感じになります。
Blob
と navigator.msSaveOrOpenBlob
を使ってファイルをローカルに保存するのを利用できるのは
IEだけで、分岐にも使えそうです。
(しかし、IE9以下は Blob
が使えないため対応してません。)
#まとめると
こんな感じになりました。
<a id="download" href="#" onclick="downloadImg();">画像ダウンロード</a>
function downloadImg () {
const fileName = 'file.png';
vonst uri = '/path/img/file.png';
// IEはdownload属性が効かないので分岐
if (window.navigator.msSaveOrOpenBlob) {
let xhr = new XMLHttpRequest();
xhr.open('GET', uri);
xhr.responseType = 'blob';
xhr.onloadend = () => {
if (xhr.status !== 200) {
return false;
}
window.navigator.msSaveOrOpenBlob(xhr.response, fileName);
};
xhr.send();
} else {
let link = document.getElementById('download');
link.href = uri;
link.download = fileName;
}
}
#気になったこと
new Blob(データ, ファイルタイプ);
みたいにBlobオブジェクトを生成した方がいいのか
今回のように、XMLHttpRequest
を使った方がいいのか
調べましたがよく分からなかったので、
詳しい方いらっしゃいましたらご教授頂けると幸いです。
#参考
download属性のブラウザ実装状況
IEのためにa要素のdownload属性を代替する
IE11にはファイルをローカルに保存するJavaScriptのAPIが2種類用意されている - Qiita