4

We're testing out pdf.js and while it seems like an awesome project we can't get it working in Safari.

(Tested on PDF.JS version = 0.8.229 (latest) / Safari 5.1.9 - 6.0.4 / Mac OSX 10.6.8 - 10.8.3)

EXAMPLE:

This is an example of the demo code served from our server with a sample PDF that works on Chrome/FFox but not Safari: http://test.appgrinders.com/pdf_js/test.html

Console output:

Warning: Setting up fake worker. 
Error: Invalid XRef stream (while reading XRef): 
Error: Invalid XRef stream pdf.js:850undefined 
Warning: Indexing all PDF objects 
Error: Invalid XRef stream (while reading XRef): 
Error: Invalid XRef stream pdf.js:850undefined

More tests:

The following is a list of sample PDFs we tested (They were all served from our server, and all worked in Chrome/FFox/Android). The only one that worked with Safari was the PDF file served from the pdf.js project itself:

FAILS IN SAFARI:
http://samplepdf.com/sample.pdf
http://forums.adobe.com/servlet/JiveServlet/previewBody/2041-102-1-2139/Sample.pdf
https://github.com/prawnpdf/prawn/raw/master/data/pdfs/form.pdf

WORKS IN SAFARI:
http://cdn.mozilla.net/pdfjs/helloworld.pdf
(NOTE: This is a sample PDF from the pdf.js project and the only one we ever got working)


We've submitted a bug report, but the developers do not seem to have an answer, so I'm hoping someone here might...

How can we get pdf.js working with Safari?

Yarin
  • 173,523
  • 149
  • 402
  • 512

6 Answers6

7

I've figured out how to get things working on Mac Safari (without necessarily understanding why)...

  1. compatibility.js must be included.

  2. PDFJS.workerSrc must be assigned.

    The demo code I had been testing (from the JS Bin demos here) does not do this, though some other online examples do (including the hello world example and the examples provided by @AndrewBenjamin – thanks). Other browsers don't seem to require this, but Safari won't work without it.

    <script type="text/javascript" src="compatibility.js"></script>
    <script type="text/javascript" src="pdf.js"></script>
    
    <!-- NEED THIS for Safari Mac to render work -->
    <script type="text/javascript">
        // Specify the main script used to create a new PDF.JS web worker.  
        // In production, change this to point to the combined `pdf.js` file.  
        PDFJS.workerSrc = 'pdf.worker.js';  
    </script>
    

Again, can't explain why, but this is how we got it working for us.

Barett
  • 5,826
  • 6
  • 51
  • 55
Yarin
  • 173,523
  • 149
  • 402
  • 512
3

I've got PDF.js working fine in Safari on my local server, but when I put it on the remote server, the goofy error comes back:

Warning: Setting up fake worker.
Unhandled rejection: Error: INVALID_STATE_ERR: DOM Exception 11

It will also show this error on my local computer if I happen to have the developer console open. Close the console, PDF displays in Safari; open the console, and it doesn't work anymore.

The question is: what do the developer tools and the remote server change versus running on a local server? Is this still a range-checking problem?

I got PDF.js to work, though! I've modified so much stuff I don't know what part of what I did worked. Here's a list of stuff I did.

  1. Added compatibility.js – modified the last function in it to read like this:

    (function checkRangeRequests() {
        var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
    
        if (!isSafari) {
            return;
        }
    
        document.addEventListener('DOMContentLoaded', function (e) {
            if (isSafari) {
                PDFJS.disableRange = true;
            }
        });
    })();
    
  2. Changed the order of xhr.open() calls in pdf.js so that xhr.setRequestHeader() occurs after xhr.open()

  3. Removed all 'use strict'; lines

  4. Added xhr.setRequestHeader("Cache-control", "no-cache"); after xhr.open on lines 37272 and 41262

  5. Minified pdf.js and it all works all the time!

AndrewBenjamin
  • 651
  • 1
  • 7
  • 16
  • Thanks for your effort, but I applied all the changes you described and am not seeing any change in results. Could there be something else you did to get it working?? – Yarin Jun 14 '13 at 13:16
  • The only version of Safari I've tested in is 5.1.7. My website where pdf.js is working is here: http://www.korenation.com/activities.html . See if it works in your safari and let me know (if it works you'll see the ugly "Rocks To The KORE" pdf floating on the right). If it does, then I'll package my files as they are and make them available to you. – AndrewBenjamin Jun 14 '13 at 15:00
  • @AndrewBenjamin- Yes, your link works on my Safari. However, when I downloaded your version of pdf.js and tried using it with my local demo, and getting a new error on Safari: pdf.js:2107Unhandled rejection: Unexpected server response (206) while retrieving PDF "http://mamp/tests/pdf_js/sample2.pdf"... – Yarin Jun 15 '13 at 00:19
  • @Yarin- I've simplified it all into a package and tested it. The online test is at www.korenation.com/test The package is in my dropbox for you to download https://www.dropbox.com/s/e1kht0w5mmho8qi/testPDFJS.zip – AndrewBenjamin Jun 15 '13 at 00:57
  • The only thing that doesn't work in Safari is the download. I'm slowly narrowing down where that problem is -- the safari debugger doesn't even detect an error -- just nothing happens. To download the pdf, any other browser will do. Firefox does it the best. If you can figure out why safari won't download the pdf, that would be great. It's always Safari that doesn't work - I've called Safari developers every name under the sun in the last two days. – AndrewBenjamin Jun 15 '13 at 01:05
  • Andrew- Thanks for all the effort, but unfortunately I can't get your code working with any of our sample PDFs. I suspect yours is working because of the way you're generating your PDFs on the client side using JSPDF. See if you can get it to render an existing file like http://test.appgrinders.com/pdf_js/sample.pdf- We couldn't. – Yarin Jun 15 '13 at 01:21
  • It works fine. Check out [link](http://www.korenation.com/test) and you should see your example pdf displaying fine. In order to do this, all I had to do was open jspdf.js, edit line 965 to read `PSFJS.getDocument('../files/pdf/sample.pdf').then(function(pdf) {` – AndrewBenjamin Jun 15 '13 at 01:40
  • jspdf is a PDF generation framework- I don't understand why/how you're using it in conjunction with pdf.js? We're not interested in re-generating PDFs on the client side, we already have them generated and stored on our servers. We just need a rendering solution that works with existing files, and it doesn't look like yours does. – Yarin Jun 15 '13 at 03:08
  • @Yarin- I only added the client side generation of pdfs today! When I started with pdf.js I was debugging it using existing pdf files. If you grab the PDFJS code (line 965-981) out of jsPDF and paste it between some – AndrewBenjamin Jun 15 '13 at 03:20
  • @AndrewBenjamin- Yea sorry, I got confused by the PDFJS class- anyway, it turns out the issue was something else altogether (see my answer) and didn't require editing of the original pdf.js files. Thanks a lot for all your effort though! – Yarin Jun 15 '13 at 17:54
0

PDFJS.getDocument() will accept either a string link or a Uint8Array. In my client side version I pass PDFJS.getDocument() a Uint8Array, but if I want an existing file rendered, I just pass the path to the file:

jspdf line 965:

PDFJS.getDocument('..files/pdf/sample.pdf').then(function(pdf) {

I don't know what makes your safari browser fail, but if you can see sample.pdf on my test site, you have to be very close to solving this.

AndrewBenjamin
  • 651
  • 1
  • 7
  • 16
0

I've figured out how to get things working on Mac Safari & iPad I removed the 'strict mode' at the beginning of

1. pdf.js/src/core/worker.js
2. pdf.js/web/download_manager.js

And worked!!

andr3s2
  • 238
  • 3
  • 10
0

if you're going to support versions below Safari 14, from what I understood PDFjs doesn't support that. you will need to use an external viewer in an object tag:

<object data="https://drive.google.com/viewerng/viewer?embedded=true&url=https://researchtorevenue.files.wordpress.com/2015/04/1r41ai10801601_fong.pdf&embedded=true"></object>
-2

I had the same problem with Safari Mobile... Can't open more than 1 Mb PDF's... I solved fragmenting the file in parts of 900 kb, join them in local and then injecting to pdf.js as Uint8Array() object. I think it's a no documented limitation.

Simón Urzúa
  • 1,556
  • 2
  • 11
  • 16