AWS SDK for JavaScript in the BrowserでAmazon S3を使ってみた


AWS SDK

10/31にAWS SDK for JavaScript in the Browserのデベロッパープレビュー版が公開されました。

ブラウザからJavaScriptを使用し、サーバーサイドのコードを書かずにAmazon S3、Amazon SNS、Amazon SQS、Amazon DynamoDBを利用できるとのことです。早速公式ブログで公開されている内容を基にAmazon S3からのファイルダウンロード、アップロードを試してみたのですが、公開されている内容だけだと少しつまづいた点があったのでメモします。

AWS SDK for JavaScript in the Browserとは?

Amazon web servicesの各サービスの機能をJavaScriptから利用可能にするSDKです。サーバーサイドの仕組みを実装することなくブラウザベースのHTMLだけで各サービスが利用できます。

2013/11/02時点では以下のAWSの以下のサービスに対応しています。

  • Amazon S3
  • Amazon SNS
  • Amazon SQS
  • Amazon DynamoDB

公式サイトと、公式ブログでの紹介は以下のリンクから参照可能です。
AWS SDK for JavaScript in the Browser (Developer Preview)
【AWS発表】開発者プレビュー版 – AWS SDK for JavaScript

事前準備

Amazon S3のサービスをSDKから使うためにS3バケットのCORS (Cross-Origin Resource Sharing)を有効化します。CORSのAllowedOriginでバケットへのGET,POST,PUT,DELETEリクエストが許可されるドメインを設定できます。

(例えば読み取りは全てのドメインから、書き込みは指定ドメインからのみ許可する等をバケット単位で設定できます。)

バケットのCORSを編集するにはAWS Management Consoleで、対象バケットの「Properties」→「Edit CORS Configuration」を開きます。
S3バケット CORS編集
CORSのエディタが開くためルールを入力します。今回はテストにつきGET,POST,PUT,DELETEについてAllowedOriginをワイルドカード(*)指定し、どのドメインからのリクエストでも読み取り・書き込み・削除を許可するよう設定しました。

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

Saveボタンを押すと設定の保存が完了します。
S3バケット CORS編集 その2

Amazon S3バケットのファイルダウンロード

S3バケットの内容と、画像を表示する処理をJavaScriptで実装し、動作確認してみます。

HTMLへの処理実装

scriptタグでAWS SDKとJQueryを読み込みます。

<script src="https://sdk.amazonaws.com/js/aws-sdk-2.0.0-rc1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

AWS.configで認証情報を指定します。

<script type="text/javascript">AWS.config.update({accessKeyId: 'YOUR_ACCESS_KEY', secretAccessKey: 'YOUR_SECRET_KEY'});</script>

※テストにつきaccessKeyIdsecretAccessKeyをハードコーディングしていますが、クライアントからアクセスキーとシークレットキーが丸見えになってしまうため推奨されていません。

認証情報はIAMでアクセス権を設定したロールを作成し、Login with AmazonやFacebook、Googleのログインと関連付け可能です。こちらのほうが推奨されている方法のようです。詳細はConfiguring the SDK in the Browserをご覧ください。

バケットとリージョンを指定し、指定されたバケットのファイル一覧と画像を表示します。
サンプルではap-northeast-1(Tokyo)リージョンを指定しています。公式ブログに記載されていたサンプルコードとほぼ同じですが、画像がpublic-readになっていないと表示されなかったのでgetSignedUrlで画像URLを取得するように変えました。

<script type="text/javascript">
    var s3BucketName = 'YOUR_BUCKET_NAME';
    var s3RegionName = 'ap-northeast-1';
    function listObjs() {
        var s3 = new AWS.S3({params: {Bucket: s3BucketName, Region:s3RegionName}});
        s3.listObjects(function(error, data) {
            if (error === null) {
                var html_keys = 'Object Keys:<br />';
                var html_imgs = '';

                jQuery.each(data.Contents, function(index, obj) {
                    var params = {Bucket: s3BucketName, Key: obj.Key};
                    var url = s3.getSignedUrl('getObject', params);
                    html_keys += (index + ': ' + obj.Key + '<br />');
                    html_imgs += "<img src='" + url + "'/><br/>";
                });
                jQuery("#objKeys").html(html_keys);
                jQuery("#objImgs").html(html_imgs);
            } else {
                console.log(error);
            }
        });
    }
</script>

ボタンを押すとファイルと画像一覧を表示するため、以下のコードを追加します。

<button onclick="listObjs()">S3 - List Objects</button>
<div id="objKeys"></div>
<div id="objImgs"></div>

動作確認

実際に動作を確認してみます。バケットにアップロードしておいたファイルは以下の画像4つです。
あらかじめバケットにアップロードしておいた画像

作成したHTMLを開くと、ボタンが表示されます。
バケットの中身表示サンプル1

ボタンを押すとバケット内のファイル名一覧と、画像が表示されます。
バケットの中身表示サンプル2

Amazon S3バケットへのファイルアップロード

同様にS3バケットへのファイルアップロードについても実装・動作確認してみます。

HTMLへの処理実装

SDKの読み込みと認証情報の指定についてはダウンロード時と同様です。

「ファイルを選択」ボタンでファイルを選び、「Upload To S3」ボタンを押すと指定したバケットにファイルがアップロードされます。(こちらは公式ブログに記載されていたサンプルと同じです。)

<script>
    AWS.config.update({accessKeyId: 'YOUR_ACCESS_KEY', secretAccessKey: 'YOUR_SECRET_KEY'});

    function uploadFile() {
        var s3BucketName = 'YOUR_BUCKET_NAME';
        
        var s3 = new AWS.S3({params: {Bucket: s3BucketName,  Region:s3BucketName}});

        var file = document.getElementById('fileToUpload').files[0];
        if (file) {
            s3.putObject({Key: file.name, ContentType: file.type, Body: file, ACL: "public-read"},
            function(err, data) {
                if (data !== null) {
                    alert("アップロード成功");
                }
                else {
                    alert("アップロード失敗");
                }
            });
        }
    }
</script>

動作確認

アップロード前の状態です。バケットには画像が4つ存在します。
あらかじめバケットにアップロードしておいた画像

「ファイルを選択」ボタンを押下してファイルを選択します。
ファイルを選択

「Upload to S3」ボタンを押下し、アップロード成功するとアラートが表示されます。
アップロード成功

アップロードされているかをManagement Consoleで確認します。確かにアップロードされています。
アップロード完了の確認

まとめ

認証情報の設定方法に気を付ける必要がありますが、本当にJavaScriptだけでAmazon S3のファイル操作ができてしまいました。Amazon S3の静的ウェブホスティングと併用すればサーバーサイドの実装なしでHTML+JavaScriptでいろんなものが作れそうです。これから対応サービスが増えてくるとさらに利用の幅が広がりそうですね。

今回テスト用に作成したHTMLはGitHubからダウンロード可能です。
https://github.com/fidn/JavaScript-s3-download-upload-sample