サーバーレスでJavaScript だけで画像ファイルをアップロードする方法
こんにちは、本間です。
今日は AWS JavaScript SDK を利用した内容です。
普通、ファイルをアップロードするにはどこかファイルを置くためのサーバーが必要ですが、Amazon S3 を使えば自前のサーバーを介さずに生のHTMLのみで直接ファイルをアップロードすることができます!
S3に直接ファイルを上げることで、サーバーの負荷を軽減することもできますし、何よりアップロード速度が早くなるのでユーザーエクスペリエンスも向上することと思います。
ちょっとした前準備が必要ですが、実装自体は極めて簡単です。それでは始めてみましょう。
Amazon Cognito で Identity Pool の作成
Amazon Cognito を利用し、アクセスの制限されたトークンを発行します。Amazon Cognito にて、Identity Pool を作成します。
name は適当に、unauthenticated identities にチェックを入れます。 unauthenticated identities とは、facebookやgoogleなどの認証を通さずにAWSへアクセスできるようにするための非認証ユーザーを許可するかの選択です。
続いて新規ロールを作成します。これはそのまま許可を選択します。ここで新規IAMロールを作成します。このIAMロールに対してアクセス権限を与えます。
これで出来上がった後に表示される、Cognito Identity Pool ID
をメモっておいてください。JavaScriptコーディング時に利用します。
IAM ロールの設定
続いて Amazon S3 にファイルをアップロードできるようにさせるためにIAMロールを設定します。
ヘッダーの名前タブ
- 認証情報
- ロール
へ移ります。ここに、先ほど作成したCognito の IAMロールがありますので、これのうち、**UnauthRole
を選択します。
ここでロールポリシーの作成
を選択し、PolicyGenerator
を選択。以下のようにセットします。
- 許可にチェック
- AWS サービスに Amazon S3を選択
- アクションに
s3:PutObject
,s3:PutObjectAcl
- リソースネームに
arn:aws:s3:::S3バケット名/*
(Amazon S3にてバケットを作成しておいてください)
S3 のバケット設定
S3側でCORS(Cross-Origin Resource Sharing)の設定をします。この設定をするからこそ、JavaScriptで外部のサーバーにAjaxを投げらるようになり、サーバーレスのアップロードができるようになります!
Amazon S3のバケットのプロパティにて、 アクセス許可
にあるCORS 設定の編集
を選択します。
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Host</AllowedHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
これにて、 AWSコンソール側の設定は完了です。
JavaScriptコーディング
こちらはあっという間にできます。
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//sdk.amazonaws.com/js/aws-sdk-2.1.34.min.js"></script>
<input type="file" name="upload" id="upload-file">
<a href="javascript:void(0)" id="apply-upload">アップロード</a>
<script>
$(function() {
var s3_client = function() {
AWS.config.region = "us-east-1";
AWS.config.credentials = new AWS.CognitoIdentityCredentials({IdentityPoolId: "Cognitoで取得したIdentity Pool Id"});
AWS.config.credentials.get(function(err) {
if (!err) {
console.log("Cognito Identify Id: " + AWS.config.credentials.identityId);
}
});
return new AWS.S3({params: {Bucket: "バケット名"}});
};
$("#apply-upload").click(function() {
var file = $("#upload-file").prop("files")[0];
var timestamp = new Date().getTime();
var filename = "file" + timestamp + ".jpg";
s3_client().putObject({Key: filename, ContentType: file.type, Body: file, ACL: "public-read"},
function(err, data){
// if failed, alert
if(data !== null){
alert("アップロード成功!");
} else {
alert("アップロード失敗.");
}
});
});
)};
</script>
こんな感じでやれば、ファイル選択してアップロードをクリックするとAmazon S3に画像がアップロードされていることでしょう。
まとめ
いかがでしたでしょうか。 ぜひお試しください。