連載
» 2016年03月30日 05時00分 UPDATE

.NET TIPS:ファイルをダウンロードさせるには?[JavaScript]

リンクをクリックするだけでファイルをダウンロードできるようにするには、HTML5のdownload属性を使う方法とJavaScriptコードを使う方法がある。

[山本康彦,BluewaterSoft/Microsoft MVP for Windows Development]
.NET TIPS
Insider.NET

 

「.NET TIPS」のインデックス

連載目次

 Webページで、エンドユーザーにファイルをダウンロードさせたいことがある。ZIPファイルなどはHTMLでリンクを記述すればよいのだが、テキストファイルやPDFファイルなどのリンクはダウンロードされずにWebブラウザで開いてしまう。何とかならないだろうか?

 本稿ではJavaScriptでファイルをダウンロードさせる方法を解説する。

HTML5のdownload属性

 JavaScriptを書き始める前に、HTML5での解決策を紹介しておこう。

 リンク(HTMLの<a>要素)には、HTML5でdownload属性が追加された。この属性に対応しているブラウザであれば、テキストファイルやPDFファイルなどでもリンクのクリックでファイルがダウンロードされる(次のコード)。

<a href="./sample.txt" download="サンプル.txt">サンプルテキスト</a>

HTML5のdownload属性の例(HTML)
<a>要素にdownload属性(太字の部分)を指定しておくと、テキストファイルなどでもWebブラウザで開かれず、ファイルとしてダウンロードされるようになる。
download属性の値が、ダウンロードされるファイル名になる(筆者の確認したところでは、Edgeはこの値を無視するようだ)。

 download属性に対応しているEdgeや最近のFirefox/Chromeなどのブラウザならば、これでどんなファイルでもダウンロードされる。では、対応していないInternet Explorer(以降、IE)などでは、どうしたらよいだろうか?

いったんメモリ上にダウンロードしてから、ファイルとして保存する

 ここでJavaScriptの出番だ。考え方としては、Webサーバからファイルをいったんメモリ上にダウンロードし、それからファイルとして保存すればよい(従って、あまり大きくないサイズのファイルに限られる)。

 メモリ上にダウンロードするには、XMLHttpRequestを使う。

 メモリ上のデータをファイルとして保存するには、Blobオブジェクトを利用する。ただし、Blobオブジェクトをファイルに保存する方法は、IE/Edgeとそれ以外のブラウザで異なる。IE/EdgeではmsSaveBlobメソッドを使う。それ以外のブラウザでは、createObjectURLメソッドを使ってBlobオブジェクトを指すURLを作り、そのURLへのリンクを生成する。

 以上をまとめると、次のコードのようになる。

<a href="./sample.txt" download="サンプル.txt"
   onclick="javascript: downloadFile('./sample.txt', 'サンプル.txt'); return false;"
   >サンプルテキスト</a>

以下に示すJavaScriptの関数をリンクのクリック時に呼び出すリンク(HTML)
onclick属性値の末尾にある「return false;」は、クリック時の<a>要素本来の動作を抑制する。
呼び出した関数内で例外が出た場合には、そこで処理は中断され、falseが返されないので、<a>要素本来の動作が実行される。こうすることで、ファイルをダウンロードするJavaScriptを実行できないブラウザでも、(エンドユーザーの追加操作は必要になるだろうが)ファイルを提供できるのだ。

function downloadFile(url, filename) {
  "use strict";

  // XMLHttpRequestオブジェクトを作成する
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.responseType = "blob"; // Blobオブジェクトとしてダウンロードする
  xhr.onload = function (oEvent) {
    // ダウンロード完了後の処理を定義する
    var blob = xhr.response;
    if (window.navigator.msSaveBlob) {
      // IEとEdge
      window.navigator.msSaveBlob(blob, filename);
    }
    else {
      // それ以外のブラウザ
      // Blobオブジェクトを指すURLオブジェクトを作る
      var objectURL = window.URL.createObjectURL(blob);
      // リンク(<a>要素)を生成し、JavaScriptからクリックする
      var link = document.createElement("a");
      document.body.appendChild(link);
      link.href = objectURL;
      link.download = filename;
      link.click();
      document.body.removeChild(link);
    }
  };
  // XMLHttpRequestオブジェクトの通信を開始する
  xhr.send();
}

ファイルをダウンロードするコードの例(JavaScript)
なお、生成したURLオブジェクトは、「window.URL.revokeObjectURL(objectURL);」のようにして破棄した方がよい。ただし、このコードの関数内で破棄してしまうと、ファイルの保存に失敗することがある(筆者の確認したところでは、Firefoxで失敗した)。

まとめ

 テキストファイルなどをダウンロードさせるには、対応しているブラウザではHTMLのリンクにdownload属性を追加すればよい。それ以外のブラウザでは、JavaScriptでいったんメモリ上にダウンロードしてから、ファイルとして保存する。

カテゴリ:JavaScript 処理対象:ファイルダウンロード
使用ライブラリ:XMLHttpRequest
使用ライブラリ:Blobオブジェクト
使用ライブラリ:msSaveBlobメソッド
使用ライブラリ:createObjectURLメソッド
関連TIPS:[ASP.NET]動的に圧縮ファイルを生成するには?
関連TIPS:[ASP.NET]データベースの内容をクライアントにダウンロード提供するには?


「.NET TIPS」のインデックス

.NET TIPS

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

Focus

- PR -

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。