こういうコードを書くたび忘れそうと思うので備忘録。
コードの方で作成した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
<button type="button" ng-click="downloadJson();">ダウンロード</button>
$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-*)のセットされたすべての要素に対して、読み取り専用のプロパティを提供するためのものです。
とのこと。
これ以外の説明はちょっと見当たらなかったのでこれも要調査