メディアファイルを<a>タグのdownload属性でダウンロードしようとすると、ブラウザによっては(特にiPhone)では、そのファイルを優先的に再生しようとします。 このため、ユーザによっては、ファイルをダウンロードする手順に戸惑う場合があります。 しかし、Blobオブジェクトを使う方法では、ブラウザがそのファイルをどう処理するかに依存することなく、ファイルを確実にダウンロードさせることができます。 なお、Blobオブジェクトは、始めて取り扱ったので、記事中の説明に誤りがあり得ることを予めご了承ください。
Blobオブジェクトについて
Blob(ブロブ)は、「Binary Large Object」の略で、大きなデータオブジェクトを指します。 主に、バイナリデータ(例えば、画像、音声、動画など)やテキストデータを処理するために使用されます。 Blobは、Web APIの一部としてHTML5の一環として導入された、JavaScriptの組み込みオブジェクトです。
Blobを経由すると確実にファイルをダウンロードできる理由
- URL.createObjectURL(blob)`メソッドを使い、ダウンロードするメディアファイルのURLをBlob URLとして一時的なURLに変換します。 このURLは、ブラウザ内でそのデータにアクセスできるようにする仮想的なリンクです。 Blob URLは、(例:blob:https://example.com/abcd1234)の様になり、元の(例えば.m4a)メディアファイルの拡張子が無いファイル名になります。
- `<a>`タグに`href`属性でBlob URLを設定し、さらに`download`属性を設定すると、リンクをクリックした際に拡張子に依存してファイルを再生しようとするブラウザの挙動を避けて確実にダウンロードすることができます。 また、ダウンロードのファイル名を例えばdownload='file1.m4a'にすれば、Blob URとは異なるファイル名'file1.m4a'で保存できます。
- 最後に、一時的に生成されたBlob URLは、ダウンロードが完了した後、`URL.revokeObjectURL(url)`で解放できます。これにより、ブラウザがメモリ内でBlob URLを保持し続けないようにします。 Blob URLはメモリリソースを消費するため、不要になったら必ず解放することが推奨されます。
PCでは、Internet Explorer 9より前のバージョン(IE8およびそれ以前)は、Blob APIをサポートしていません。 モバイルでは、古いAndroidブラウザ(Android 2.x)やiOSのSafariのバージョン(iOS 6以前など)では、Blob APIがサポートされていない場合があります。 詳しくは、URL:https://caniuse.com/?search=Blob
メディアファイルをBlobを経由してダウンロードする方法
メディアファイルを<a>タグのclass="download" 要素に関連付けて、このclass要素がクリックされたときに data-url 属性から URL を抽出しBlob を経由してそのメディアファイルをダウンロードさせるためのscriptコードは以下のようになります。 ここでは、音声ファイル(audio_file.m4a)の例を示します。
HTML <a class="download" href="#ダミー" data-url="https://ドメイン/pass/audio_file.m4a"> Down Load</a>HTMLコードの<a>タグの説明
通常、hrefにダウンロードするファイル(url)を記述しますが、hrefにファイルurlを記述していないことに注意してください。 代わりに、blobに引き渡すダウンロード・ファイルのurlを data-url に記述します。
Blobを経由してダウンロードするscript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
jQuery(document).ready(function($) { // ボタンクリック時の処理 $('.download').click(function() { // data-url 属性から URL を抽出 var fileUrl = $(this).data('url'); var file_name = fileUrl.split('/').pop();//フルパスのfileUrlからファイル名を抽出(file1.m4a など) // ダイアログを表示 var confirmDownload = window.confirm(file_name + '\nをダウンロードしますか?'); if(!confirmDownload) { return false; } // いいえで、処理終了 // ファイルをBlobとして読み込み、ダウンロードリンクを作成 fetch(fileUrl) .then(response => response.blob()) // Blobとしてデータを取得 .then(blob => { var url = URL.createObjectURL(blob); // Blob URLを作成 console.log(url);// 生成したURLをコンソールに表示 デバック用 // ここから、ダウンロード用リンクを作成 var link = document.createElement('a'); link.href = url; link.download = file_name; // download属性にファイル名を設定 // ダウンロードを実行 link.click(); // ダウンロード後にURLオブジェクトを解放 URL.revokeObjectURL(url); }); }); }); |
このscriptの配置場所
Affinger6の場合、AFFINGER管理から、 その他 > 「上級者向け」の </body>直前に出力するコード欄に記述します。 他の方法として、フッターにコードを挿入できるWPCode Lite プラグイン(リンクへ)を使って配置する方法もあります。
scriptコードの説明
2行目:class="download"要素がクリックされたら、このscriptが発火します。
3行目:data-url 属性から URLを抽出して、fileUrlに代入しています。
4行目:fileUrl からファイル名(file_name)を抽出するために、split('/') を使って URL を / で分割し、pop() を使って最後の部分(ファイル名)を取得します。 例えば、fileUrl が https://ドメイン/pass/audio_file.m4a" であれば、audio_file.m4a がファイル名として設定されます。
6,7行目:ダウンロードするファイル(fileUrl)を付記して、ダウンロードするか否かのダイアログを表示します。
9行目以降の説明(Blob処理)
- fetch(fileUrl)
最初に fetch() メソッドが呼ばれ、指定された サーバーのURL (fileUrl) からデータを取得します。 fetch() は非同期で、fetch() が成功するとレスポンスを Response オブジェクトとして返します。 - .then(response => response.blob())
.thenメソッド は、Promise の結果を処理し、複数の処理をつなぎ、順番に実行することが出来ます。 fetch() のレスポンスを受け取った後、そのレスポンスデータを blob() メソッドで変換しています。 - .then(blob => { ... })
blob を受け取った後の処理が続きます。この部分のコードでは、Blob データを使ってダウンロード用のリンクを作成しています。 - var url = URL.createObjectURL(blob);
Blob を元に一時的な Blob URLを作成します。これによって、ブラウザ内でこのデータにアクセスできるようになります。URL.createObjectURL() は、指定された blob を指す Blob URL を返します。 - var link = document.createElement('a');
<a> タグを JavaScript で動的に作成しています。 - link.href = url;
作成した<a>タグの href 属性に、先ほど作成したBlob URL を設定します。 - link.download = file_name
ダウンロード時のファイル名をdownload属性で設定しています。 - link.click();
<a> タグが作成され、必要な属性が設定された後、click() メソッドを使って、ダウンロードを開始します。 - URL.revokeObjectURL(url);
最後に、作成したオブジェクト URL を解放しています。URL.revokeObjectURL() を使って、この一時的な URL を無効にします。これにより、メモリリークを防ぎます。
Blobを経由してメディアファイルのダウンロード例(AACファイルの場合)
ダウンロード元の ♬ AAC(160kbps 48khz)ファイルを聴く
〜〜 音源クレジット 〜〜
バッハ管弦楽組曲 第2番 ポロネーズ 録音:Studio 1961年6月
指揮:カール・ミュンヒンガー ( Fl.)ジャン=ピエール・ランパル 、 シュトゥットガルト室内管弦楽団
Londonレーベル盤よりハイレゾ収録しafconvertでAAC(160kbps 48khz)ファイルに変換
実例
1 <a>タグを利用してAACファイルをダウンロードする
HTML <a class="download" href="#ダミー" data-url="https://ドメイン/pass/audio_file.m4a"> AAC 160kbps Down Load</a>
バッハ管弦楽組曲 第2番 ポロネーズ
実例
2 <button>タグを利用してAACファイルをダウンロードする
HTML <button class="download" data-url="https://ドメイン/pass/audio_file.m4a">Download ボタン</button>
実例
3 Affinger6のミニ・ボタンを利用してAACファイルをダウンロードする
HTML <div class="download" style="width: fit-content; margin: 0 auto;" data-url="https://ドメイン/pass/audio_file.m4a">[st-mybutton-mini ]</div>