30
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaScriptで画像をダウンロードしたい

Last updated at Posted at 2018-12-05

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つの違いについては、こちら で詳しく説明されているので参考までにどうぞ。

実際にやってみると

HTML側
<a onclick="downloadImg();">画像ダウンロード</a>
JavaScript側
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();
}

こんな感じになります。

Blobnavigator.msSaveOrOpenBlob を使ってファイルをローカルに保存するのを利用できるのは
IEだけで、分岐にも使えそうです。

(しかし、IE9以下は Blob が使えないため対応してません。)

#まとめると
こんな感じになりました。

HTML側
<a id="download" href="#" onclick="downloadImg();">画像ダウンロード</a>
JavaScript側
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

30
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?