AWS SDK for JavaScriptを使ってS3にダイレクトでファイルをアップロードする
AWS SDK for JavaScriptがリリースされました。これにより、例えばS3にJavaScriptのファイルを配置して、クライアントサイドでJavaScriptを実行、その中でS3へのファイルアップロードの処理を行えば、別途S3へのアップロードを行うためのWebサーバが必要なくなります。
まず、最初にJavaScriptを使って、S3のバケットに対してlistObjectsしてみます。そのJavaScriptを含むHTMLファイルが以下です。
<head> <title>Sample</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <body> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.0.0-rc1.min.js"></script> <script type="text/javascript"> <!-- AWS.config.update({accessKeyId: 'ACCESS_KEY_ID', secretAccessKey: 'SECRET_ACCESS_KEY'}); var s3 = new AWS.S3({region: 'ap-northeast-1', maxRetries: 15}); s3.listObjects({Bucket: 'BUCKET_NAME'}, function(error, data) { if (error) { console.log(error); // an error occurred } else { console.log(data); // request succeeded } }); // --> </script> </body> </html>
これをWebサーバもしくはS3上に配置します。
この作業だけでは、Access Deniedと表示されてしまうので、さらに該当するバケットのCORS(Cross-Origin Resource Sharing)を設定します。CORSとは、S3とは違う他のドメインのサイトからS3上のリソースにアクセスするときの共有設定のことです。デフォルトではAllowedOriginが*のものに対して、GETメソッドのみ許可されているようです。それを以下のように変更します。
<CORSConfiguration> <CORSRule> <AllowedHeader>*</AllowedHeader> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <AllowedHeader>Authorization</AllowedHeader> </CORSRule> </CORSConfiguration>
※AllowedOriginを、特定のURL(例:http://www.example.com/)に限定すると、より権限を限定できて良いです。
FirefoxのプラグインのFirebugを使って、Console Logを見てみると、以下のようにコンテンツを取得できていることがわかりました。
次に本記事のメインとなるS3 Uploadを試してみます。
以下のようなs3upload.htmlを作成しました。
<html> <head> <title>Sample</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <body> <input type="file" id="file-chooser" /> <button id="upload-button">Upload to S3</button> <div id="results"></div> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.0.0-rc1.min.js"></script> <script type="text/javascript"> <!-- AWS.config.update({accessKeyId: 'AKIAXXXXXXXXXXXXXX', secretAccessKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'}); var bucket = new AWS.S3({params: {Bucket: 'BUCKET-NAME'}}); var fileChooser = document.getElementById('file-chooser'); var button = document.getElementById('upload-button'); var results = document.getElementById('results'); button.addEventListener('click', function() { var file = fileChooser.files[0]; if (file) { results.innerHTML = ''; var params = {Key: file.name, ContentType: file.type, Body: file}; bucket.putObject(params, function (err, data) { results.innerHTML = err ? 'ERROR!' : 'UPLOADED.'; }); } else { results.innerHTML = 'Nothing to upload.'; } }, false); // --> </script> </body> </html>
作成したs3upload.htmlを表示すると以下のような画面が表示されます。
適当なテキストファイルを選択してアップロードすると、以下のように表示されます。
S3 Management Consoleで確認すると、確かにアップロードされてました!
あとは、JavaScript内にAWS Security Credential情報がベタ書きされてしまっているのを、以前書いた記事にあるようにSecurity Token Serviceを使って、一時的なTokenを使うようにすれば、権限を制限させることもできます。
以上ですー。