質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

0回答

1883閲覧

【Laravel】【Vuejs】動的に生成したファイルをjavascript経由でダウンロードしたい

hasshy

総合スコア102

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/11/26 22:03

編集2022/01/12 10:55

PDFの書類を動的に生成するアプリケーションを作成しています。
DomPDFでPDFを生成しているのですが、ダウンロードを開始するまで数秒かかってしまいます。
ダウンロード開始まで画面に動きがないのでユーザーが不安になるかと考えています。

そのため、javascriptでローディングのような事が出来ないか考えています。
非同期でファイルを生成して、ダウンロードするまでのローディングを表示できれば改善できるかと考えています。

ただ、ファイルの生成してフロントエンドで受け取ることはできるのですが、ダウンロードの処理が動作しません。
恐らく、Laravel環境が起因していると考えているのですが、解決方法が見つかりません。

ご助言をいただけないでしょうか?

お伺いしたい事

Laravelの場合、URLのルーティングを設定します。
そのため、javascriptのURL.createObjectURL()で生成されたURLもこのルーティングが適用されてしまいます。
回避方法はあるのでしょうか?
それとも、別の箇所に問題があるのでしょうか?

ソース

バックエンド

ルーター

下記にアクセスすると、application/pdfのデータが返って来ます。

https://example.com/api/user/1/pdf/download

php

1// router/api.php 2Route::get('/users/{user}/pdf/download', 'Api\TestController@downloadPDF')

コントローラー

Laravel-Dompdfでファイルを生成して、戻り値はpdfの内容をbodyに設定して返します。
下記のテストコードは簡単ですが、実際にはbladeテンプレートで動的に表示する要素が多数あります。

php

1// Http/Controllers/TestController.php 2 3public function downloadPDF { 4 $pdf = \PDF::loadView('pdf_template'); 5 return $pdf->download('sample.pdf'); 6}

フロントエンド

PDFをAPI経由で取得してダウンロードする処理です。
レスポンスで返ってきたファイル、URL.createObjectURLで生成されたURLからダウンロードさせたいと考えています。

javascript

1<template lang="pug"> 2a(@click.prevent.stop="downloadPDF()") ダウンロード 3</template> 4 5<script> 6 import axios from 'axios'; 7 8 export default { 9 name: "DownloadPDFButton", 10 props: { 11 hotNewsId: { 12 type: Number, 13 required: true 14 } 15 }, 16 methods: { 17 downloadPDF() { 18 axios.get('https://example.com/api/user/1/pdf/download', { 19 responseType: 'blob', 20 params: { 21 api_token: '(APIトークン)' 22 } 23 }).then(response => { 24 console.log("ok"); 25 const file = new Blob( 26 [response.data], 27 { 28 type: 'application/pdf' 29 }, 30 ); 31 32 // リンクを作成して発火 33 const link = document.createElement('a'); 34 let fileUrl = URL.createObjectURL(file); 35 link.download = 'test.pdf'; 36 link.click(); 37 38 // リンク無効化 39 setTimeout(function() { 40 window.URL.revokeObjectURL(fileUrl); 41 }); 42 43 }).catch(function() { 44 // ダウンロード失敗 45 console.log('error'); 46 }) 47 }, 48 } 49 } 50 51</script>

状況

下記で一時的なリンクを発火させましたが、ダウンロードが始まりません。

js

1// リンクを作成して発火 2const link = document.createElement('a'); 3let fileUrl = URL.createObjectURL(file); 4link.download = 'test.pdf'; 5link.click();

所見

お伺いしたいことに記載しましたが、恐らくURL.createObjectURL(file) で生成されたURLが、Laravelのルートに干渉してしまったのではないかと考えます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問