ExpressでPOSTされたBase64のデータを画像としてS3に保存する

2 min read読了の目安(約2000字

はじめに

こんにちはIT系専門学校三年の氏本といいます
学校の制作コンテストの様なものでBase64のデータをS3に保存する処理を書きました。
(CanvasをBase64にして送信してました。)
処理を書くにあたって色々な記事を参考にして書いたのですが個々の処理の解説記事はあるものの
Base64をS3にアップロードする一連の流れの説明を書いていた記事が見当たらなかったのでアウトプットの練習も兼ねて書いてみました。

環境

node.js v14.17.0(LTS)

npm

  • express
  • urlsafe-base64
  • aws-sdk

AWS

S3のバケットが一つ用意できればいいです。

参考程度ですがパケットポリシーはこんな感じです。ここら辺は割と雰囲気でやってます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::バケット名/フォルダ名/*"
        }
    ]
}

express

構造

  • app.js
  • views
    • index.ejs
    • post.ejs
  • node_modules
  • config
    • aws.js

app.js

細かい設定とかは省きます。
一応Postで送れるデータのサイズを最大50MBに設定してます。(50MBはかなり適当な値です。)

const express = require("express")
const app = express()
const AWS = require("aws-sdk")
const s3 = new AWS.S3()

// AWSの設定ファイル
const config = {
    accessKeyId: "xxxxx",
    secretAccessKey: "xxxxx",
    region: "region"
}
// 複数ファイルで使う場合は↓こう
// const config = require("./config/aws")


app.use(express.urlencoded({extended: true, limit: "50mb"}));

// 中略~~~

app.get("/",(req,res)=>{
    res.render("index");
})

app.post("/post",(req,res)=>{
    // 後で解説していきます
})

app.listen(3000)

Base64デコード

base64のデコードには今回urlsafe-base64を使用しました。

const base64 = require("urlsafe-base64")
const base64_data = req.body.base64_data
const decode_data = base64.decode(base64_data.replace("data:image/png;base64,", ""))

base64.decodeでデコードする事ができますがどうも先頭の"data:image/png;base64,"を削除しないといけないみたいです。

S3アップロード

const params = {
    Bucket: "bucket-name",
    Key: `/ファイル名.png`,
    Body: decode_data,
    ContentType: "image/png"
}
s3.putObject(params,(err, data) => {
    if(err){
        console.log("失敗")
        return
    }
    console.log("upload完了")
})

これでアップロードできます。

保存した画像をimgタグなどで取得したい場合paramsのContentTypeを"image/png"にしないと画像として扱ってくれないみたいなので気を付けてください。