We announced
Viewing Photos in an Amazon S3 Bucket from a Browser
This browser script code example shows:
-
How to create a photo album in an Amazon Simple Storage Service (Amazon S3) bucket and allow unauthenticated users to view the photos.
The Scenario
In this example, a simple HTML page provides a browser-based application for viewing the photos in a photo album. The photo album is in an Amazon S3 bucket into which photos are uploaded.
![JavaScript in a browser script using Amazon S3 buckets for photo albums.](images/images_bjs/s3-photo-album-example.png)
The browser script uses the SDK for JavaScript to interact with an Amazon S3 bucket. The script uses the listObjects
method of the Amazon S3 client class to enable you to view the photo albums.
Prerequisite Tasks
To set up and run this example, first complete these tasks.
Note
In this example, you must use the same Amazon Region for both the Amazon S3 bucket and the Amazon Cognito identity pool.
In the Amazon S3 console
As you create the S3 bucket, be sure to do the following:
-
Make note of the bucket name so you can use it in a subsequent prerequisite task, Configure Role Permissions.
-
Choose an Amazon Region to create the bucket in. This must be the same Region that you'll use to create an Amazon Cognito identity pool in a subsequent prerequisite task, Create an Identity Pool.
-
Configure bucket permissions by following Setting permissions for website access in the Amazon Simple Storage Service User Guide.
In the Amazon Cognito console
As you create the identity pool, make note of the identity pool name, as well as the role name for the unauthenticated identity.
To allow viewing of albums and photos, you have to add permissions to an IAM role of the identity pool that you just created. Start by creating a policy as follows.
Open the IAM console
. In the navigation pane on the left, choose Policies, and then choose the Create policy button.
-
On the JSON tab, enter the following JSON definition, but replace BUCKET_NAME with the name of the bucket.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::
BUCKET_NAME
" ] } ] } -
Choose the Review policy button, name the policy and provide a description (if you want), and then choose the Create policy button.
Be sure to make note of the name so that you can find it and attach it to the IAM role later.
After the policy is created, navigate back to the IAM console
Although the workflow for this task is generally the same as Step 2: Add a Policy to the Created IAM Role of the Getting Started in a Browser Script topic, there are a few differences to note:
-
Use the new policy that you just created, not a policy for Amazon Polly.
-
On the Attach Permissions page, to quickly find the new policy, open the Filter policies list and choose Customer managed.
For additional information about creating an IAM role, see Creating a Role to Delegate Permissions to an Amazon Service in the IAM User Guide.
Before the browser script can access the Amazon S3 bucket, you have to set up its CORS configuration as follows.
Important
In the new S3 console, the CORS configuration must be JSON.
Because this example only allows users to view the photos that are already in the bucket, you need to create some albums in the bucket and upload photos to them.
Note
For this example, the file names of the photo files must start with a single underscore ("_"). This character is important later for filtering. In addition, be sure to respect the copyrights of the owners of the photos.
-
In the Amazon S3 console
, open the bucket that you created earlier. -
On the Overview tab, choose the Create folder button to create folders. For this example, name the folders "album1", "album2", and "album3".
-
For album1 and then album2, select the folder and then upload photos to it as follows:
-
Choose the Upload button.
-
Drag or choose the photo files you want to use, and then choose Next.
-
Under Manage public permissions, choose Grant public read access to this object(s).
-
Choose the Upload button (in the lower-left corner).
-
-
Leave album3 empty.
Defining the Webpage
The HTML for the photo-viewing application consists of a <div>
element in which the browser script creates the viewing interface. The first <script>
element adds the SDK to the browser script. The second <script>
element adds the external JavaScript file that holds the browser script code.
For this example, the file is named PhotoViewer.js
, and is located in the same folder as the HTML file. To find the current SDK_VERSION_NUMBER, see the API Reference for the SDK for JavaScript at Amazon SDK for JavaScript API Reference Guide.
<!DOCTYPE html> <html> <head> <!-- **DO THIS**: --> <!-- Replace SDK_VERSION_NUMBER with the current SDK version number --> <script src="https://sdk.amazonaws.com/js/aws-sdk-SDK_VERSION_NUMBER.js"></script> <script src="./PhotoViewer.js"></script> <script>listAlbums();</script> </head> <body> <h1>Photo Album Viewer</h1> <div id="viewer" /> </body> </html>
Configuring the SDK
Obtain the credentials you need to configure the SDK by calling the CognitoIdentityCredentials
method. You need to provide the Amazon Cognito identity pool ID. Then create an AWS.S3
service object.
// **DO THIS**: // Replace BUCKET_NAME with the bucket name. // var albumBucketName = "BUCKET_NAME"; // **DO THIS**: // Replace this block of code with the sample code located at: // Cognito -- Manage Identity Pools -- [identity_pool_name] -- Sample Code -- JavaScript // // Initialize the Amazon Cognito credentials provider AWS.config.region = "REGION"; // Region AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: "IDENTITY_POOL_ID", }); // Create a new service object var s3 = new AWS.S3({ apiVersion: "2006-03-01", params: { Bucket: albumBucketName }, }); // A utility function to create HTML. function getHtml(template) { return template.join("\n"); }
The rest of the code in this example defines the following functions to gather and present information about the albums and photos in the bucket.
-
listAlbums
-
viewAlbum
Listing Albums in the Bucket
To list all of the existing albums in the bucket, the application's listAlbums
function calls the listObjects
method of the AWS.S3
service object. The function uses the CommonPrefixes
property so that the call returns only objects that are used as albums (that is, the folders).
The rest of the function takes the list of albums from the Amazon S3 bucket and generates the HTML needed to display the album list on the webpage.
// List the photo albums that exist in the bucket. function listAlbums() { s3.listObjects({ Delimiter: "/" }, function (err, data) { if (err) { return alert("There was an error listing your albums: " + err.message); } else { var albums = data.CommonPrefixes.map(function (commonPrefix) { var prefix = commonPrefix.Prefix; var albumName = decodeURIComponent(prefix.replace("/", "")); return getHtml([ "<li>", '<button style="margin:5px;" onclick="viewAlbum(\'' + albumName + "')\">", albumName, "</button>", "</li>", ]); }); var message = albums.length ? getHtml(["<p>Click on an album name to view it.</p>"]) : "<p>You do not have any albums. Please Create album."; var htmlTemplate = [ "<h2>Albums</h2>", message, "<ul>", getHtml(albums), "</ul>", ]; document.getElementById("viewer").innerHTML = getHtml(htmlTemplate); } }); }
Viewing an Album
To display the contents of an album in the Amazon S3 bucket, the application's viewAlbum
function takes an album name and creates the Amazon S3 key for that album. The function then calls the listObjects
method of the AWS.S3
service object to obtain a list of all the objects (the photos) in the album.
The rest of the function takes the list of objects that are in the album and generates the HTML needed to display the photos on the webpage.
// Show the photos that exist in an album. function viewAlbum(albumName) { var albumPhotosKey = encodeURIComponent(albumName) + "/"; s3.listObjects({ Prefix: albumPhotosKey }, function (err, data) { if (err) { return alert("There was an error viewing your album: " + err.message); } // 'this' references the AWS.Request instance that represents the response var href = this.request.httpRequest.endpoint.href; var bucketUrl = href + albumBucketName + "/"; var photos = data.Contents.map(function (photo) { var photoKey = photo.Key; var photoUrl = bucketUrl + encodeURIComponent(photoKey); return getHtml([ "<span>", "<div>", "<br/>", '<img style="width:128px;height:128px;" src="' + photoUrl + '"/>', "</div>", "<div>", "<span>", photoKey.replace(albumPhotosKey, ""), "</span>", "</div>", "</span>", ]); }); var message = photos.length ? "<p>The following photos are present.</p>" : "<p>There are no photos in this album.</p>"; var htmlTemplate = [ "<div>", '<button onclick="listAlbums()">', "Back To Albums", "</button>", "</div>", "<h2>", "Album: " + albumName, "</h2>", message, "<div>", getHtml(photos), "</div>", "<h2>", "End of Album: " + albumName, "</h2>", "<div>", '<button onclick="listAlbums()">', "Back To Albums", "</button>", "</div>", ]; document.getElementById("viewer").innerHTML = getHtml(htmlTemplate); document .getElementsByTagName("img")[0] .setAttribute("style", "display:none;"); }); }