axiosを使った強制ダウンロードGETリクエスト
vuejs 2 + axiosを使っています。 getリクエストを送信し、いくつかのパラメータをサーバーに渡し、レスポンスとしてPDFを取得する必要があります。サーバーはLaravelを使用しています。
そこで
axios.get(`order-results/${id}/export-pdf`, { params: { ... }})
はリクエストに成功しましたが、サーバーが正しいヘッダを返したにもかかわらず、強制ダウンロードを開始しませんでした。
これは、例えばPDFレポートを作成し、いくつかのフィルタをサーバに渡す必要がある場合の典型的な状況だと思います。では、どうすれば実現できるのでしょうか?
**更新
実は解決策を見つけました。しかし、同じ方法はaxiosではうまくいかなかった。そこで、blobオブジェクトを作成して、createUrlObject
関数を使用することで解決しました。サンプル例:
let xhr = new XMLHttpRequest()
xhr.open('POST', Vue.config.baseUrl + `order-results/${id}/export-pdf`, true)
xhr.setRequestHeader("Authorization", 'Bearer ' + this.token())
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xhr.responseType = 'arraybuffer'
xhr.onload = function(e) {
if (this.status === 200) {
let blob = new Blob([this.response], { type:"application/pdf" })
let link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'Results.pdf'
link.click()
}
}
**重要:レスポンスタイプとして配列バッファを指定する必要があります。
しかし、axiosで同じコードを書くと、空のPDFが返されます:
axios.post(`order-results/${id}/export-pdf`, {
data,
responseType: 'arraybuffer'
}).then((response) => {
console.log(response)
let blob = new Blob([response.data], { type: 'application/pdf' } ),
url = window.URL.createObjectURL(blob)
window.open(url); // Mostly the same, I was just experimenting with different approaches, tried link.click, iframe and other solutions
})
31
5
サーバにデータが渡されていないため、空のPDFが表示されています。次のようにデータオブジェクトを使ってデータを渡してみてください。
これを試して: Internet Explorer 11との互換性により、私にとっては完全に機能します(createObjectURLはExplorer 11では機能しません)。
https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743。
アクシオスやAJAXでこれを行うことは不可能だと思います。ファイルはメモリ上に保存されます。つまり、ファイルをディスクに保存することはできません。JavaScriptはディスクとやりとりできないからです。これは重大なセキュリティ問題であり、すべての主要なブラウザでブロックされています。
フロントエンドでURLを作成し、以下の方法でダウンロードすることができます:
お役に立てれば幸いです!
上記の提案されたアプローチのいくつかを試しましたが、私の場合、ブラウザからポップアップブロック警告が送信されました。 以下で説明するコードは私のために機能しました:
結局、リンクを作成してそこからダウンロードした。
スタックオーバーフローの別の質問のanswerにその方法の詳細を書きました。