Vue/HTML/JS downloadタグを使ってファイルをブラウザにダウンロードする方法


スポンサーリンク

私の質問はVUEに焦点を当てており、VUEにもデフォルトの方法を防ぐ方法があるのかどうかという点で、この質問は提供された他の回答とは異なります。

この質問は、HTML 5 の「ダウンロード」と VUE による :href の結合に特化したもので、なぜ新しいタブでファイルを開くというデフォルトのブラウザの動作を防ぐことができないのかを説明しています。

期待される動作 : ファイルをブラウザにダウンロードする

実際の動作 : 新しいタブでファイルを開く

例外です。新しいタブで開かれるのは、画像、PDF、ブラウザ互換性のあるファイルのみで、.exeなどの他のファイルは通常通りダウンロードされます - これはなぜですか、この動作はhtmlで変更できますか?

target="_blank "を追加しても、問題は解決しません。

<a :href="downloadById(item.url)" download>Download</a>

上記のリンクをクリックすると、ファイルが新しいブラウザタブで開かれますが、このデフォルトの動作を防止し、クリック時にダウンロードを強制する必要があります。この問題を解決するためには、HTML 5の「download」タグを使用する必要がありますが、これがうまく機能しないようです。

Chromeは最近、クロスドメインダウンロードに対応したdownloadタグを廃止しました。vueには、このデフォルトを防ぐモディファイアはありますか?javascriptまたはhtmlでファイルをダウンロードする他の方法はありますか?

1つの提案された解決策は、URLをarrayBufferとして読み込み、DOM内に新しいblobを作成し、アンカー要素を作成してそれをクリックするというものです。しかし、これではファイルを強制的にダウンロードすることになってしまい、使い勝手が悪そうです。

URLからファイルをダウンロードするには、もっとすっきりとした解決策があるはずで、些細な問題なので、シンプルな解決策を期待しています。

回答

ファイルをblobとして取得し、同じように提供すれば、CORSの問題につながるリクエストは発生しません。

Template

<a
  :href="item.url"
  v-text="item.label"
  @click.prevent="downloadItem(item)" />

Vue

methods: {
  downloadItem ({ url, label }) {
    Axios.get(url, { responseType: 'blob' })
      .then(response => {
        const blob = new Blob([response.data], { type: 'application/pdf' })
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = label
        link.click()
        URL.revokeObjectURL(link.href)
      }).catch(console.error)
  }
}