2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Conoha VPS] ReactからNode経由でオブジェクトストレージへ画像保存する方法

Last updated at Posted at 2021-12-18

#はじめに
Webアプリを作る際にConohaのオブジェクトストレージに画像をアップロードするのが大変でしたので記事に書きました。
回覧板アプリ
サーバーサイドのNodeを経由した理由は、データベースでユーザー情報と画像ファイル名を紐付けして管理したいからです。

#画像アップロードの流れ
私が作成したWebアプリ内で画像アップロード方法は以下のようにしています。
1.ReactからNodeに画像を送信
2.NodeのMulterを使って、VPS内のフォルダに画像データを一時保存
3.オブジェクトストレージのトークン取得
4.NodeでVPSで一時保存している画像データをオブジェクトストレージへ送信
5.VPS内の一時保存している画像データを削除

#Conohaのオブジェクトストレージとは
Conohaが提供しているオブジェクトストレージで、特徴としては以下の通りです。
Conohaオブジェクトストレージ
1.データ転送料金無料
2.容量無制限
3.三重データコピーで耐障害性・信頼性
4.100GBあたり月額495円
5.RESTful API対応

#1.ReactからNodeに画像を送信
axiosを使ってNodeに画像を送信しています。
以下はフックの関数です。

useUpdateImage.ts
const updateUserImage = useCallback((props: Props) => {

        const { imageFile } = props;
        const data = new FormData();
        if (imageFile !== null){data.append('file', imageFile)};
        const header = { 
            headers: {
            "content-type": "multipart/form-data"
            }
        }

        axios.post('APIのパス', data, header).then((res) => {
            if(!res.data.success){
                console.log('エラーです');
            } else {
                console.log('成功です');
            }           
        }).catch((error) => {
            console.log(error);
        })
}, [])

#2.NodeのMulterを使って、VPS内のフォルダに画像データを一時保存
次にMulterを使って、Reactから送られてきた画像データをVPS内フォルダに保存します。
Multer

server.js
const multer = require('multer');
const uuid = require('uuid').v4;

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, 'public/temporary') //一時的に画像を保存するパスを指定
    },
    filename: (req, file, cb) => {
        const { originalname } = file; //画像のオリジナルネームの取得
        const fileName = encodeURI(`${uuid()}-${originalname}`); //uuidで差別化した名前に変更
        cb(null, fileName);
    }
})

const uploadAsync = (req, res) => {
    return new Promise((resolve, reject) => {
        upload(req,res,function(err){
            if (err instanceof multer.MulterError) {
                // A Multer error occurred when uploading.
                reject(err);
              } else if (err) {
                // An unknown error occurred when uploading.
                reject(err);
              }
            else {resolve()}
        });
    })
}

//画像アップロードのAPI
app.post('APIのパス',
    (req, res, next) => {
        uploadAsync(req, res).then(() => {
            const file = req.file;
            const imageName = file.filename;   
            //トークン取得など続きの動作がここから入る
            })
     }
)

#3.オブジェクトストレージのトークン取得
次にオブジェクトストレージのトークンを取得します。

server.js
const _ = require('lodash');
const httpRequest = require('request');

//以下にVPS内のAPI情報を入力します。
const tenantId = 'テナントID';
const username = 'ユーザー名';
const password = '設定したパスワード';

const api_url = 'https://identity.tyo2.conoha.io/v2.0';

const params = {
    "url": api_url+'/tokens',
    "headers": {
        "Accept": 'application/json'
    },
    "form": JSON.stringify({
        "auth": {
            "passwordCredentials": {
                "username": username,
                "password": password
            },
            "tenantId": tenantId
        }
    })
};

app.post('APIのパス',
    (req, res, next) => {
        uploadAsync(req, res).then(() => {
            const file = req.file;
            const imageName = file.filename;   
            //トークン取得
            httpRequest.post(params, function(err, result, body){
                if (_.isString(body)) {
                    const res = JSON.parse(body);
                    const token = res.access.token.id;
                    const token_expire = res.access.token.expires;
                    console.log('token: ' + token);
                    console.log('expire: ' + token_expire);
                    //画像アップロード等の動作が続く

                } else {
                    const res = body;
                    console.log(res);
                }
            })
        })
     }
)

#4.NodeでVPSで一時保存している画像データをオブジェクトストレージへ送信
最後に一時保存している画像データをオブジェクトストレージに送信します。

server.js
app.post('APIのパス',
    (req, res, next) => {
        uploadAsync(req, res).then(() => {
            const file = req.file;
            const imageName = file.filename;   
            //トークン取得
            httpRequest.post(params, function(err, result, body){
                if (_.isString(body)) {
                    const res = JSON.parse(body);
                    const token = res.access.token.id;
                    const token_expire = res.access.token.expires;
                    console.log('token: ' + token);
                    console.log('expire: ' + token_expire);

                    //画像アップロード

                    //ヘッダーの設定
                    const headers = {
                        'X-Auth-Token': token,
                        "Transfer-Encoding":"chunked"
                    };

                    // 送信先など
                    const options = {
                        //API情報に記載のあるオブジェクトストレージAPIエンドポイント
                        url: `https://object-storage.tyo2.conoha.io/v1/・・・/・・・/${imageName}`, 
                        headers: headers,
                    }

                    fs.createReadStream(`public/temporary/${imageName}`)
                    .pipe(httpRequest.put( options , function(err , response , body){
                      console.log( response.headers );
                      console.log( 'ステータスコード:',response.statusCode);
                      console.log( body );
                      if(err)console.log(err);
                      else {
                        console.log( 'アップロードしました' );
                      }
                    }

                } else {
                    const res = body;
                    console.log(res);
                }
            })
        })
     }
)

#5.VPS内の一時保存している画像データを削除
VPS内で一時保存している画像データは不要なので削除します。

server.js
fs.unlink(`public/temporary/${imageName}`, (err) => {
  if (err) throw err;
})

#参考
Conohaのオブジェクトストレージを使ってみた(REST API Ver)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?