JavaScriptだけでファイルのダウンロードなんてできっこない、そういうのはバックエンドの領分でしょ。そう思っていた時期が私にもありました。しかし先日、実はできるということがわかったので、今回はJavaScriptだけでjsonファイルをダウンロードするのに挑戦したいと思います。

応用すれば複数のapiからデータを取得して、jsで合体させてから1ファイルとしてダウンロードなんてこともできてしまう! 夢が広がりますね。

Blobオブジェクトを作る

早速ですが、ダウンロードファイルを作るためにはBlobオブジェクトというものを使います。オブジェクトの作り方は次の通り。

const blob = new Blob(blobParts[, options]);

MDNのドキュメントによると、blobPartsの方にファイル化したいデータを渡し、optionsでファイル形式を指定するみたいですね。今回はオブジェクト形式のデータをjsonファイルとしてダウンロードしたいので、コードはこんな感じ↓になります。

const data = {
  name: 'diwao',
  url: 'http://diwao.com'
};

const blob = new Blob([JSON.stringify(data, null, '  ')], {type: 'application\/json'});

上のコードのblobをconsole.logで見てみるとこうなってました。

Blob {size: 50, type: "application/json"}

ちゃんとオブジェクトは作れたみたいですね。

ダウンロード用のURLを作る

さて、続いてはURL.createObjectURLメソッドを使って、ファイルをダウンロードするときに必要となるURLの生成をやっていきましょう。

URL.createObjectURLメソッドは、FileオブジェクトかBlobオブジェクトを引数として受け取り、受け取ったオブジェクトを表すURLを生成します。コードにするとこうですね。

const url = URL.createObjectURL(blob);

あとはここで作ったurlをa要素に設定し、download属性を利用すればダウンロードできるようになります。

デモ

実際にファイルダウンロードを実行できるデモを作ってみました。input要素に入力した内容をjsonファイルとしてダウンロードできる、というものです。

See the Pen file download sample by diwao (@diwao) on CodePen.

MacのChrome(59)、Safari(10.1.1)で動作確認済み。FireFoxは動きませんでした。MDNのドキュメントにも、BlobはJavaScriptネイティブなフォーマットではない、URL.createObjectURLは実験段階の機能であるなどの記述があったので、まだ実際の案件で使うのは難しいかもですね。試してないけどIEは動かなさそう……。

とはいえ、利用ブラウザが限定された管理画面などでは使いどころあると思うので、こういうこともできるというのは覚えておいて損はないかと。

参考