Yarin
Yarin

Reputation: 183989

pdf.js not working with Safari

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?

Upvotes: 4

Views: 24073

Answers (6)

Ahlam
Ahlam

Reputation: 11

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>

Upvotes: 0

andr3s2
andr3s2

Reputation: 278

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!!

Upvotes: 0

Yarin
Yarin

Reputation: 183989

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.

Upvotes: 7

AndrewBenjamin
AndrewBenjamin

Reputation: 779

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!

Upvotes: 3

Sim&#243;n Urz&#250;a
Sim&#243;n Urz&#250;a

Reputation: 1546

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.

Upvotes: -2

AndrewBenjamin
AndrewBenjamin

Reputation: 779

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.

Upvotes: 0

Related Questions