1

I am trying to view a generated PDF in a page rendered in PHP. The PDF file actually does not exist on the server, so there is no URL for the file. The issue that I am having is that the FireFox viewer works (the built in one works fine), but Chrome one does not because it uses the URL when the user tries to download the file, and the URL does not have a filename appended to it since the file is not accessible via a URL. In Firefox, it works if I send headers like:

header('Content-type:' . $mimetype); // application/pdf
header('Content-disposition: ' . $disposition . '; filename="'.$filename.'"');
header('content-Transfer-Encoding:binary');
header('Accept-Ranges:bytes');
readfile($targetfile);  // the path to the PDF, outside of server root.

The alternative I am looking at is using the Mozilla pdf.js library so that the Mozilla viewer is used for all browsers, which would be nice because the Mozilla viewer is nice and I'll pick up some other capabilities if using that library.

I looked at a couple of other posts on SO.

How do I display all pages in a PDF (stored in base64) using PDF.js?

pdf.js rendering as PDF with base64

That does not work, no PDF, but the js files are loading and it just display some sort of generic viewer code without a PDF.

The viewer.html file in the web directory starts with:

See https://github.com/adobe-type-tools/cmap-resources
-->
<html dir="ltr" mozdisallowselectionprint>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!--#if GENERIC || CHROME-->
    <meta name="google" content="notranslate">
<!--#endif-->
<!--#if GENERIC-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--#endif-->
    <title>PDF.js viewer</title>

This is what I am rendering adapted from the 1st reference.

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">    
    <script src="/js/pdf.js-master/src/pdf.js"></script>
    <script src="/js/pdf.js-master/web/pdfjs.js"></script>
    <link src ="/js/pdf.js-master/web/viewer.css">
</head>
  <body>
    <iframe id="pdfFrame" style="width:900px;height:1000px;"></iframe>
    <script>
        function base64ToUint8Array(base64) {
            var raw = atob(base64);
            var uint8Array = new Uint8Array(raw.length);
            for (var i = 0; i < raw.length; i++) {
              uint8Array[i] = raw.charCodeAt(i);
            }
            return uint8Array;
          }
        var pdfData = base64ToUint8Array("<?php echo $output; ?>");
        var pdfViewerFrame = document.getElementById("pdfFrame");
        pdfViewerFrame.onload = function() {
            pdfViewerFrame.contentWindow.PDFViewerApplication.open(pdfData);
        }
        pdfViewerFrame.setAttribute("src","/js/pdf.js-master/web/pdf_viewer.js?file=");     
    </script>
  </body>
</html>

Any suggestions appreciated. base_viewer.js is in the web folder in the master package, same directory as the viewer.html file. I have not tried embedding in an object or iframe, but I would probably have the same issue with the filename getting lost like in Chrome.

When I post via the Controller I get the filename to use from the file. The file is out of web root, which is why it is created dynamically without a URL.

$path_parts = pathinfo($targetfile);
$mimetype = self::getMimeType($path_parts['extension']);
$disposition = $_POST['disposition'];

For some reason when you just render with headers:

header('Content-type:' . $mimetype);
header('Content-disposition: ' . $disposition . '; filename="'.$filename.'"');
header('content-Transfer-Encoding:binary');
header('Accept-Ranges:bytes');
readfile($targetfile);

Firefox preserves the filename, but the Chrome viewer uses the name from the URL slug, which is not a URL to an actual PDF. $filename = $path_parts['basename'];

That just gives an error:

/* Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { BaseViewer } from "./base_viewer.js";
import { shadow } from "pdfjs-lib";

class PDFViewer extends BaseViewer {

... ...

Probably just some sort of configuration issue

SScotti
  • 2,158
  • 4
  • 23
  • 41

0 Answers0