sushicat
sushicat

Reputation: 115

Cannot download base64 encoded pdf displayed in chrome browser

I'm displaying base64 encoded files within the built-in chrome viewer. No matter if it is a jpg or PDF I'm unable to download it via button or right click. All other functionality such as rotate and print works however.. The tab title displayed is just a 'Loading' with a spinner as well. I am able to download it in firefox just fine.

let fileDisplayUrl = '<iframe src="' + 'data:' + mimeType + ';base64,' + base64Contents + '"frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;"></iframe>';
let win = window.open();       
win.document.write(fileDisplayUrl);

I'm thinking it's due to the way I'm displaying it but I haven't had lucks with other ways yet.

Edit: Tried these as object and img tags and same issue on those.

Upvotes: 3

Views: 4931

Answers (1)

tevemadar
tevemadar

Reputation: 13195

Your actual problem is more like that you can not download content supplied via a data:-URI from a new window. Side note: the spinner can be stopped via close()-ing the document, but it does not affect the inoperational "Save as".

Two workarounds I found:

  1. Open data in the current window (the "iframe" button does that, then the document can be downloaded via right-clicking, though its name defaults to "download.pdf" in Chrome). It may be an option with short documents / small images
  2. It is possible to provide an explicit button for downloading, and in this case a filename can be supplied too. "window(tab)" button does that in the example. While generally it does not look nice that the exact same encoded data is moved around twice, it happens locally in the browser after all

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script>
            let pdf="JVBERi0xLjIgCjkgMCBvYmoKPDwKPj4Kc3RyZWFtCkJULyA5IFRmKFRlc3QpJyBFVAplbmRzdHJlYW0KZW5kb2JqCjQgMCBvYmoKPDwKL1R5cGUgL1BhZ2UKL1BhcmVudCA1IDAgUgovQ29udGVudHMgOSAwIFIKPj4KZW5kb2JqCjUgMCBvYmoKPDwKL0tpZHMgWzQgMCBSIF0KL0NvdW50IDEKL1R5cGUgL1BhZ2VzCi9NZWRpYUJveCBbIDAgMCA5OSA5IF0KPj4KZW5kb2JqCjMgMCBvYmoKPDwKL1BhZ2VzIDUgMCBSCi9UeXBlIC9DYXRhbG9nCj4+CmVuZG9iagp0cmFpbGVyCjw8Ci9Sb290IDMgMCBSCj4+CiUlRU9G";
            function doFrame(){
                let frm=document.createElement("iframe");
                frm.style="border-color:black";
                frm.src="data:application/pdf;base64,"+pdf;
                document.body.appendChild(frm);
            }
            function doWindow(){
                let wnd=open("",Date.now());
                let doc=wnd.document.open();
                doc.write("<a href='data:application/pdf;base64,"+pdf+"' download='small.pdf'>Download</a><br>");
                doc.write("Object<br><object type='application/pdf' data='data:application/pdf;base64,"+pdf+"'></object><br>");
                doc.write("Embed<br><embed type='application/pdf' src='data:application/pdf;base64,"+pdf+"'><br>");
                doc.write("IFrame<br><iframe src='data:application/pdf;base64,"+pdf+"'/>");
                doc.close();
            }
        </script>
    </head>
    <body>
        <button onclick="doWindow()">window(tab)</button><br>
        <button onclick="doFrame()">iframe</button><br>
    </body>
</html>

It's not a runnable snippet as the security sandbox here (on StackOverflow) blocks both kind of attempts.
The "window(tab)" variant opens the pdf as object, embed and iframe too, I can confirm that right-click+"Save as" in Chrome does not do anything on them. Download button works (also, in Chrome at least).

Upvotes: 1

Related Questions