AWS SDK for JavaScript
SDK v2 開発者ガイド

ブラウザから Amazon S3 への写真のアップロード


                JavaScript code example that applies to browser execution

このブラウザスクリプトコード例では以下を示します。

  • ユーザーが Amazon S3 バケットにフォトアルバムを作成し、そのアルバムに写真をアップロードできるようにする、ブラウザアプリケーションの作成方法。

シナリオ

この例では、シンプルな HTML ページが、写真をアップロードできる Amazon S3 バケットにフォトアルバムを作成するためのブラウザベースのアプリケーションを提供します。アプリケーションを使用すると、追加した写真やアルバムを削除することができます。


                フォトアルバムに Amazon S3 バケットを使用したブラウザスクリプト内の JavaScript。

ブラウザスクリプトは SDK for JavaScript を使用して Amazon S3 バケットと連携します。フォトアルバムアプリケーションを有効にするには、Amazon S3 クライアントクラスの次のメソッドを使用します。

前提条件タスク

この例をセットアップして実行するには、まず次のタスクを完了する必要があります。

  • Amazon S3 コンソールで、アルバムに写真を保存するために使用する Amazon S3 バケットを作成します。コンソールでバケットを作成する方法の詳細については、Amazon Simple Storage Service コンソールユーザーガイド の「バケットの作成」を参照してください。オブジェクトに対して [Read (読み取り)] と [Write (書き込み)] の両方の権限があることを確認してください。

  • Amazon Cognito コンソールで、Amazon S3 バケットと同じリージョンの認証されていないユーザーに対してアクセスが有効になっているフェデレーテッドアイデンティティを使用して Amazon Cognito ID プールを作成します。コード内の ID プール ID を含めて、ブラウザスクリプトの認証情報を取得する必要があります。Amazon Cognito フェデレーテッドアイデンティティに関する詳細については、Amazon Cognito 開発者ガイド の「Amazon Cognito アイデンティティ プール (フェデレーテッドアイデンティティ)」を参照してください。

  • IAM コンソールで、認証されていないユーザー用に Amazon Cognito によって作成された IAM を見つけます。次のポリシーを追加し、Amazon S3 バケットに読み取りおよび書き込み権限を付与します。IAM ロールの作成の詳細については、IAM ユーザーガイド の「AWS のサービスにアクセス許可を委任するロールの作成」を参照してください。

    認証されていないユーザー用に Amazon Cognito によって作成された IAM ロールに、このロールポリシーを使用します。

    警告

    認証されていないユーザーに対してアクセスを有効にした場合は、世界中のすべてのユーザーに、バケット、およびバケット内のすべてのオブジェクトへの書き込みアクセス許可が付与されます。このセキュリティ体制がこの例で便利なのは、この例の主な目的に焦点を合わせるためです。多くの実況では、ただし、認証されたユーザーとオブジェクトの所有権を使用するなど、セキュリティを強化することを強くお勧めします。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:DeleteObject", "s3:GetObject", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::BUCKET_NAME/*" ] } ] }

CORS の設定

ブラウザスクリプトが Amazon S3 バケットにアクセスする前に、まず次のように CORS 設定をセットアップする必要があります。

<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedMethod>HEAD</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration>

ウェブページ

写真アップロードアプリケーションの HTML は、ブラウザスクリプトがアップロードユーザーインターフェイスを作成する <div> 要素で構成されています。最初の <script> 要素は SDK をブラウザスクリプトに追加します。2 番目の <script> 要素はブラウザのスクリプトコードを保持する外部 JavaScript ファイルを追加します。

<!DOCTYPE html> <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.283.1.min.js"></script> <script src="./app.js"></script> <script> function getHtml(template) { return template.join('\n'); } listAlbums(); </script> </head> <body> <h1>My Photo Albums App</h1> <div id="app"></div> </body> </html>

SDK の設定

CognitoIdentityCredentials メソッドを呼び出して SDK を設定するために必要な認証情報を取得し、Amazon Cognito ID プール ID を指定します。次に、AWS.S3 サービスオブジェクトを作成します。

var albumBucketName = "BUCKET_NAME"; var bucketRegion = "REGION"; var IdentityPoolId = "IDENTITY_POOL_ID"; AWS.config.update({ region: bucketRegion, credentials: new AWS.CognitoIdentityCredentials({ IdentityPoolId: IdentityPoolId }) }); var s3 = new AWS.S3({ apiVersion: "2006-03-01", params: { Bucket: albumBucketName } });

この例の残りのコードのほとんどすべては、バケット内のアルバムに関する情報を収集して表示し、アルバムにアップロードされた写真をアップロードして表示し、写真とアルバムを削除する一連の関数に整理されます。これらの関数は以下の通りです。

  • listAlbums

  • createAlbum

  • viewAlbum

  • addPhoto

  • deleteAlbum

  • deletePhoto

バケット内のアルバムの一覧表示

アプリケーションは、キーがスラッシュ文字で始まるオブジェクトとして Amazon S3 バケットにアルバムを作成し、そのオブジェクトがフォルダとして機能していることを示します。バケット内のすべての既存アルバムを一覧表示するには、commonPrefix の使用時に、アプリケーションの listAlbums 関数が AWS.S3 サービスオブジェクトの listObjects メソッドを呼び出します。呼び出しはアルバムとして使用されているオブジェクトのみを返します。

残りの関数は Amazon S3 バケットからアルバムのリストを取得して、ウェブページにアルバムのリストを表示するために必要な HTML を生成します。個々のアルバムを削除したり開いたりすることもできます。

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>", "<span onclick=\"deleteAlbum('" + albumName + "')\">X</span>", "<span onclick=\"viewAlbum('" + albumName + "')\">", albumName, "</span>", "</li>" ]); }); var message = albums.length ? getHtml([ "<p>Click on an album name to view it.</p>", "<p>Click on the X to delete the album.</p>" ]) : "<p>You do not have any albums. Please Create album."; var htmlTemplate = [ "<h2>Albums</h2>", message, "<ul>", getHtml(albums), "</ul>", "<button onclick=\"createAlbum(prompt('Enter Album Name:'))\">", "Create New Album", "</button>" ]; document.getElementById("app").innerHTML = getHtml(htmlTemplate); } }); }

バケット内にアルバムを作成する

Amazon S3 バケットにアルバムを作成するには、アプリケーションの createAlbum 関数がまず新しいアルバムに付けられた名前を検証し、適切な文字が含まれていることを確認します。次に関数は Amazon S3 オブジェクトキーを作成し、それを Amazon S3 サービスオブジェクトの headObject メソッドに渡します。このメソッドは指定されたキーのメタデータを返すので、データを返す場合、そのキーを持つオブジェクトはすでに存在しています。

アルバムがまだ存在しない場合、関数は、AWS.S3 サービスオブジェクトの putObject メソッドを呼び出し、アルバムを作成します。次に、viewAlbum 関数を呼び出し、新しい空のアルバムを表示します。

function createAlbum(albumName) { albumName = albumName.trim(); if (!albumName) { return alert("Album names must contain at least one non-space character."); } if (albumName.indexOf("/") !== -1) { return alert("Album names cannot contain slashes."); } var albumKey = encodeURIComponent(albumName) + "/"; s3.headObject({ Key: albumKey }, function(err, data) { if (!err) { return alert("Album already exists."); } if (err.code !== "NotFound") { return alert("There was an error creating your album: " + err.message); } s3.putObject({ Key: albumKey }, function(err, data) { if (err) { return alert("There was an error creating your album: " + err.message); } alert("Successfully created album."); viewAlbum(albumName); }); }); }

アルバムの表示

Amazon S3 バケット内のアルバムの内容を表示するには、アプリケーションの viewAlbum 関数は、アルバム名を取得して、そのアルバムの Amazon S3 キーを作成します。この関数は、AWS.S3 サービスオブジェクトの listObjects メソッドを呼び出して、アルバム内のすべてのオブジェクト (写真) のリストを取得します。

残りの関数はアルバムからオブジェクト (写真) のリストを取得して、ウェブページに写真を表示するために必要な HTML を生成します。個々の写真を削除したり、アルバムのリストに戻ったりすることもできます。

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.Response 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>", '<img style="width:128px;height:128px;" src="' + photoUrl + '"/>', "</div>", "<div>", "<span onclick=\"deletePhoto('" + albumName + "','" + photoKey + "')\">", "X", "</span>", "<span>", photoKey.replace(albumPhotosKey, ""), "</span>", "</div>", "</span>" ]); }); var message = photos.length ? "<p>Click on the X to delete the photo</p>" : "<p>You do not have any photos in this album. Please add photos.</p>"; var htmlTemplate = [ "<h2>", "Album: " + albumName, "</h2>", message, "<div>", getHtml(photos), "</div>", '<input id="photoupload" type="file" accept="image/*">', '<button id="addphoto" onclick="addPhoto(\'' + albumName + "')\">", "Add Photo", "</button>", '<button onclick="listAlbums()">', "Back To Albums", "</button>" ]; document.getElementById("app").innerHTML = getHtml(htmlTemplate); }); }

アルバムに写真を追加する

Amazon S3 バケット内のアルバムに写真をアップロードするには、アプリケーションの addPhoto 関数がウェブページのファイルピッカーエレメントを使用して、アップロードするファイルを特定します。次に、現在のアルバム名とファイル名から写真をアップロードするためのキーを作成します。

関数は、Amazon S3 サービスオブジェクトの upload メソッドを呼び出し、写真をアップロードします。ACL パラメータを public-read に設定すると、アプリケーションはアルバム内の写真を取り出してバケット内の URL で表示することができます。写真をアップロードすると、アップロードされた写真が表示されるように、関数はアルバムを再表示します。

function addPhoto(albumName) { var files = document.getElementById("photoupload").files; if (!files.length) { return alert("Please choose a file to upload first."); } var file = files[0]; var fileName = file.name; var albumPhotosKey = encodeURIComponent(albumName) + "//"; var photoKey = albumPhotosKey + fileName; // Use S3 ManagedUpload class as it supports multipart uploads var upload = new AWS.S3.ManagedUpload({ params: { Bucket: albumBucketName, Key: photoKey, Body: file, ACL: "public-read" } }); var promise = upload.promise(); promise.then( function(data) { alert("Successfully uploaded photo."); viewAlbum(albumName); }, function(err) { return alert("There was an error uploading your photo: ", err.message); } ); }

写真の削除

Amazon S3 バケットのアルバムから写真を削除するには、アプリケーションの deletePhoto 関数が Amazon S3 サービスオブジェクトの deleteObject メソッドを呼び出します。これにより、関数に渡された photoKey の値で指定された写真が削除されます。

function deletePhoto(albumName, photoKey) { s3.deleteObject({ Key: photoKey }, function(err, data) { if (err) { return alert("There was an error deleting your photo: ", err.message); } alert("Successfully deleted photo."); viewAlbum(albumName); }); }

アルバムの削除

Amazon S3 バケットのアルバムを削除するには、アプリケーションの deleteAlbum 関数が Amazon S3 サービスオブジェクトの deleteObjects メソッドを呼び出します。

function deleteAlbum(albumName) { var albumKey = encodeURIComponent(albumName) + "/"; s3.listObjects({ Prefix: albumKey }, function(err, data) { if (err) { return alert("There was an error deleting your album: ", err.message); } var objects = data.Contents.map(function(object) { return { Key: object.Key }; }); s3.deleteObjects( { Delete: { Objects: objects, Quiet: true } }, function(err, data) { if (err) { return alert("There was an error deleting your album: ", err.message); } alert("Successfully deleted album."); listAlbums(); } ); }); }