ブラウザでBase64で受け取ったファイルをダウンロードする
受託開発担当のRyuです。
先日、サーバからBase64で受け取ったPDFをそのままダウンロードしたい場面に出くわしました。
難なく出来るだろうと高をくくっていたのですが、つまづいたのでメモとして残します。
簡単に流れを説明すると、Base64をBlobへと変換し、それをBlob URL Schemeとしてリンクタグに動的に埋め込み、強制的にそれを叩きます。
<script type="text/javascript" src="jquery-3.1.1.min.js"></script> <script type="text/javascript"> $(function() { $ajax(~中略~) .done(function(data, type) { downloadPdf(data); }); }); /** * Base64とMIMEコンテンツタイプからBlobオブジェクトを作成する。 * * @param base64 */ function downloadPdf (base64) { var mime_ctype = "application/pdf"; var blob = toBlob(data, mime_ctype); if (window.navigator.msSaveBlob) { // IEやEdgeの場合、Blob URL Schemeへと変換しなくともダウンロードできる window.navigator.msSaveOrOpenBlob(blob, "file.pdf"); } else { // BlobをBlob URL Schemeへ変換してリンクタグへ埋め込む $("#file_dl").prop("href", window.URL.createObjectURL(blob)); // リンクをクリックする document.getElementById("file_dl").click(); } } /** * Base64とMIMEコンテンツタイプからBlobオブジェクトを作成する。 * 日本語対応。 * * @param base64 * @param mime_ctype MIMEコンテンツタイプ * @returns Blob */ function toBlob(base64, mime_ctype) { // 日本語の文字化けに対処するためBOMを作成する。 var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); var bin = atob(base64.replace(/^.*,/, '')); var buffer = new Uint8Array(bin.length); for (var i = 0; i < bin.length; i++) { buffer[i] = bin.charCodeAt(i); } // Blobを作成 try { var blob = new Blob([bom, buffer.buffer], { type: mime_ctype, }); } catch (e) { return false; } return blob; } </script>
http://amaraimusi.sakura.ne.jp/note_prg/JavaScript/file_binary.html
http://qiita.com/wadahiro/items/eb50ac6bbe2e18cf8813
この辺りを参考にさせてもらいました。
なお、ダウンロードではなくブラウザで表示させるだけの場合は、Base64のままData URI schemeを使えば可能なようです。