9

I try to display a .doc file stored on a S3 bucket inside an iframe thanks to google doc viewer api.

I already did some research and found this, which i tried to apply here :

var encodedUrl = encodeURIComponent("http://myAPI.com/1d293950-67b2-11e7-8530-318c83fb9802/example.docx?X-Amz-Algorithm=AWS4-HMAC-SHA256%26X-Amz-Credential=GNRO0BLDYAJP1FU7ALIS%2F20170717%2Fus-east-1%2Fs3%2Faws4_request%26X-Amz-Date=20170717T145429Z%26X-Amz-Expires=600%26X-Amz-SignedHeaders=host%26X-Amz-Signature=ee556c5c92427bb38265507218a701660936bc2774ecc919648bb2d780a2619f");

$scope.selectedSource = $sce.trustAsResourceUrl(
   "http://docs.google.com/gview?url=" + encodedUrl + "&embedded=true"
);

Iframe looks like :

<iframe ng-src="{{selectedSource}}" frameborder="no" style="width:100%;height:100%"></iframe>

But i still get a "No Preview Available" from the viewer inside the iframe , any idea why ?

I specify that the signed url (not encoded) works when I paste it in my browser, so I have all the rights needed.

Gambo
  • 1,572
  • 3
  • 26
  • 52
Nuzzob
  • 371
  • 1
  • 4
  • 23
  • This works for me using a pre-signed URL from S3, opening a new browser tab and going to a slightly different URL: `https://docs.google.com/viewer?url=` + the redundantly url-encoded (which is technically what you're doing, and seems correct) pre-signed S3 URL (Signature Version 4). The alternate Google URL was spotted [here](https://webapps.stackexchange.com/q/44673/83083). You might want to test it in its own window before you try embedding it, to eliminate variables. – Michael - sqlbot Jul 17 '17 at 19:35
  • Link is dead and not working – Jatin Dhoot Jan 27 '21 at 10:20

1 Answers1

11

The Amazon S3 Presigned URL contains query string parameters, so it contains "?" and "&" which confuses the outer URL.

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

Like this:

var encodedUrl = encodeURIComponent(presigned_url);
var iFrameUrl = 'https://docs.google.com/gview?url=' + encodedUrl;

OR (using S3 .NET Core API)

using (AmazonS3Client S3Client = new AmazonS3Client(accKey, secKey, new AmazonS3Config() { ServiceURL = serviceUrl }))
{
      GetPreSignedUrlRequest getPreSignedUrl = new GetPreSignedUrlRequest
      {
             BucketName = s3BucketName,
             Key = fileName,
             Expires = DateTime.Now.AddMinutes(30)
      };
      encoded_SignedUrl = WebUtility.UrlEncode(S3Client.GetPreSignedURL(getPreSignedUrl));
 }
m2pathan
  • 360
  • 2
  • 17