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のルートに干渉してしまったのではないかと考えます。
あなたの回答
tips
プレビュー