ブラウザから Amazon S3 への写真のアップロード - AWS SDK for JavaScript

AWS SDK for JavaScript v2 のサポート終了が間近に迫っていることが発表されています。AWS SDK for JavaScript v3 に移行することをお勧めします。日付、その他の詳細、移行方法については、リンク先の発表内容を参照してください。

ブラウザから 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 ユーザーガイドの「バケットの作成」を参照してください。オブジェクト読み取りおよび書き込みの両方の許可があることを確認してください。バケットの許可の設定の詳細については、ウェブサイトアクセスに必要な許可の設定を参照してください。

  • Amazon Cognito コンソールで、Amazon S3 バケットと同じリージョンの認証されていないユーザーに対してアクセスが有効になっているフェデレーテッドアイデンティティを使用して Amazon Cognito アイデンティティプールを作成します。コード内の 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:ListBucket", "s3:PutObject", "s3:PutObjectAcl" ], "Resource": [ "arn:aws:s3:::BUCKET_NAME", "arn:aws:s3:::BUCKET_NAME/*" ] } ] }

CORS の設定

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

重要

新しい S3 コンソールでは、CORS 設定は JSON である必要があります。

JSON
[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "HEAD", "GET", "PUT", "POST", "DELETE" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [ "ETag" ] } ]
XML
<?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> <ExposeHeader>ETag</ExposeHeader> </CORSRule> </CORSConfiguration>

ウェブページ

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

<!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="./s3_photoExample.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 を提供します。次に、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 メソッドを呼び出し、写真をアップロードします。写真をアップロードすると、アップロードされた写真が表示されるように、関数はアルバムを再表示します。

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, }, }); 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(); } ); }); }