Help us understand the problem. What is going on with this article?

jsでダウンロードを実装した話

こういうコードを書くたび忘れそうと思うので備忘録。

コードの方で作成したjsonオブジェクトをファイルに書き込み、ダウンロードするボタンを作りました。
ボタンクリックすると遷移なしでダウンロードが始まる感じです。
ちなみに下記ではAndular使ってますので、使ってない場合は適宜修正してください

さっそく実装

HTML5ではdownload属性にファイル名、hrefにファイルパスを指定することでファイルをダウンロードできます。

<a href="download/acme-doc-2.0.1.txt" download="Acme Documentation (ver. 2.0.1).txt">Download Text</a>

しかしこれで僕がやりたいことをやるには

  • ファイルを適当な場所に作成、保存
  • その保存場所をhrefに指定してダウンロード

と二度手間になってしまう。
ボタンを押すだけで、コードの別の部分で作ったjsonをそのままファイルに書き込み、保存し、ダウンロードしたかったんです。
探したらありました。下記を参考に書いてみます。
http://kuroeveryday.blogspot.jp/2015/07/javascript-upload-download.html
https://elearn.jp/jmemo/javascript/memo-325.html

html側
<button type="button" ng-click="downloadJson();">ダウンロード</button>
js側
$scope.downloadJson = function () {
          //ファイルを作ってダウンロードします。
          var resultJson = JSON.stringify($scope.jsonObj);
          var downLoadLink = document.createElement("a");
          downLoadLink.download = $scope.fileName;
          downLoadLink.href = URL.createObjectURL(new Blob([resultJson], {type: "text.plain"}));
          downLoadLink.dataset.downloadurl = ["text/plain", downLoadLink.download, downLoadLink.href].join(":");
          downLoadLink.click();
      }

上記のdownload属性をhtmlで設定する代わりにjsでcreateElementを使って設定しています。
気になる(というかぱっと見でよくわからなかった)のは

URL.createObjectURL(new Blob([resultJson], {type: "text.plain"}))

downLoadLink.dataset.downloadurl = ["text/plain", downLoadLink.download, downLoadLink.href].join(":");

の部分。

URL.createObjectURLについて

こちらにいろいろ書いてありました。
http://hakuhin.jp/js/blob_url_scheme.html

Blob URL Schemeというものを生成するメソッドだそうです。
要するにオブジェクトを指定するとそこからランダムな文字列動的に生成してURLに使うもので、
URLにディレクトリ名が入らないので機密性が保証されると。
具体的な生成法は不明です。ていうかわかったらまずいですよね…
ちなみに大容量のデータでも重くならないらしいです。この辺はよくわからないので要調査。

dataset.downloadurlについて

https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/dataset
こちらのサイトによると、

カスタムdata属性 (data-*)のセットされたすべての要素に対して、読み取り専用のプロパティを提供するためのものです。

とのこと。
これ以外の説明はちょっと見当たらなかったのでこれも要調査

Ohtak
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away