THE BITESITE BLOG
Amazons3googledocspreview

Google Docs Viewer with Amazon S3 Private Documents and Presigned URLs

coding software

So recently one of our developers discovered an awesome service that Google Docs provides called the Google Docs Viewer. It's super powerful and super easy to use. Basically, it's a service that allows you to pass a URL of a document to this service, and it will render a preview of the document that's usable in the DOM. This is amazing for providing previews of common documents like PDF, DOCs and more. We saw Trello use it so we thought it's gotta be a good solution.

Here's an example:

<iframe src='https://docs.google.com/viewer?url=http://www.bitesite.ca/Signing%20up%20for%20Amazon%20S3.pdf&embedded=true'></iframe>

You could slap that iFrame into your HTML and boom, you have a preview of a PDF document embedded in your website.

However, the app that we were building was using private, protected documents hosted on Amazon S3. So to pass a URL to the Google Docs Viewer, we had to get a presigned URL. So it would look something like this:

<iframe src='https://docs.google.com/viewer?url=AMAZON_S3_PRESIGNED_URL&embedded=true'></iframe>

As soon as we did this, we kept getting a "No Preview Available" error from Google Docs. After trying lots of solutions, it turns out the error had to do with the fact that we were passing a URL with Query String params as a query string param to another URL. That is, the Amazon S3 Presigned URL contains query string parameters, so it contains a "?" and "&" which confuses the outer URL.

So long story short, you have to Encode the S3 Presigned URL before passing it to the Google Doc Viewer.

If you're using Presigned URLs, my guess is that you're dynamically setting the URL. We do it with Javascript, so our code looks something like this:

var encodedUrl = encodeURIComponent(amazon_presigned_url);
var iFrameUrl = 'https://docs.google.com/viewer?url=' + encodedUrl + '&embedded=true';

We did run into an issue where we tried encodeURI instead of encodeURIComponent, but that was just our misunderstanding of those methods. If you're doing server-side encoding, make sure you're it's correctly removing "/", "?", and "&".

Alright, that's it for now. Hopefully this helps out some peeps.

Caseyli
Casey Li
CEO & Founder, BiteSite