Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8913

【node+Vue】ストア+APIを経由してサーバで作ったバイナリファイル受け取りダウンロードさせる

$
0
0

リアクティブでSPAでなければ、サーバサイドにPOSTしてファイルをダウンロードさせれば簡単だけど
v-router とか使うと簡単には行かず、困ったのだけれど、
以下の方法で受け渡しできたので備忘録として記載しておく。

【仕様】
・ダウンロードボタンを押すと、サーバ側で作成されたファイルをダウンロードする。

【前提】
・vue から直接サーバ側へはPOSTできない。(ルーターが邪魔する。)
・ストア+API経由でサーバ側とのデータのやり取りはできる。

【サーバ側実装】
今回は、API経由でデータが渡されると、サーバ側でファイルを作成し、base64エンコードした内容を
json形式で { DATA: xxxx } として返すようにした。

【クライアント側実装】
こんな感じ
今回の肝は以下の2箇所。
・base64 をデコードする部分
・blobファイルをダウンロードさせる部分。

methods: {
  /**
   * ダウンロード
   */
  async download() {
    let info = { // api に渡す引数があれば、こんな感じで受け渡す。
      name: "download.csv"
    };
    let data = await this.$store.dispatch("download", { info });

    // base64をデコードする。
    let base64 = data["DATA"];
    let bin = atob(base64.replace(/^.*,/, ''));
    let buffer = new Uint8Array(bin.length);
    for (var i = 0; i < bin.length; i++) {
      buffer[i] = bin.charCodeAt(i);
    }

    // 以下のコードが実行されると、勝手にファイルがダウンロードされる。
    const blob = new Blob([buffer.buffer], { type: 'application/csv'});
    let link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = 'download.csv';
    link.click();
  }
},

download() を呼び出すボタンはこんな感じ。

<v-btn text @click="download" v-bind="attrs" v-on="on">
<v-icon>mdi-download</v-icon>
</v-btn>

直接、サーバサイドにPOSTできれば簡単だったけれど、そうすると他とセオリーが異なってしまう。
ボタンが押されると、すぐ遷移してそちらで処理されるのとは異なり、
ボタンが押されると非同期で axios 通信が行われ、データを受け取った後にダウンロードされることになる。


Viewing all articles
Browse latest Browse all 8913

Trending Articles