Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ziaulrehman40/23e55156571f57aeb3053c3b8ceff0d0 to your computer and use it in GitHub Desktop.
Save ziaulrehman40/23e55156571f57aeb3053c3b8ceff0d0 to your computer and use it in GitHub Desktop.
Integrate PDF.js plugin in rails apps to properly display PDFs hosted on S3 in iframe on ipads/iphones, solving problem that ipads only display frist page of pdf

Integrate PDF.js plugin in rails apps

PDF.js is a plugin for displaying pdfs in webpages, it solves a problem on ipads too(indirectly) where ipads and iphones only render first page of the pdf and users can't scroll pdfs rendered in iframes.

pdfjs_rails is the gem which we are going to use for integrating PDF.js in rails.

This gem is pretty old and not maintained, its last commit in master was 5 years ago(at the time of writing). But nevertheless it works and you can easily get you pdfs working in iPads and iPhone. tada!

There are only a few steps which i had to perform to get it working for S3 hosted files on non-public buckets.

You also have to use following CORS setting, as PDF.js sends an AJAX request after page load:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <ExposeHeader>Accept-Ranges</ExposeHeader>
    <ExposeHeader>Content-Encoding</ExposeHeader>
    <ExposeHeader>Content-Length</ExposeHeader>
    <ExposeHeader>Content-Range</ExposeHeader>
    <AllowedHeader>Range</AllowedHeader>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Steps

  1. Install gem(follow its readme)
  2. Set CORS setting of your bucket as described above.
  3. As you have ran this command rails g pdfjs_rails:install while installing gem, this generates a lot of files. You can delete the locale files you dont need generated by this gem.

Real issue:

The real problem was in one of JS files genrated by this gem, which tries to parse url of the PDF file(hosted on S3 in our case). It was taking only small portion of url, ignoring all headers etc sent along the url.

To solve this problem, open the file: public/pdfjs/web/viewer.js , generated by the gem. And on line number 3803 you should see following line, or search for this line otherwise:

document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {

In this method it is parsing the url with some weird logic, which removes extra data from our S3 hosted PDF. I had to modify its first few lines to look something like:

document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {

  PDFView.initialize();

  var params = document.location.search.substring(1);

  var file = params.substr(5) || DEFAULT_URL;

params.substr(5) is to remove file=(5 characters) from the params.

Don't see any need to go into details of this change, you can analyze this code yourself. This is what is working for us now. You can put console logs in old code and new code to see whats different.

Happy coding!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment