Node.jsを使用してWebアプリケーションからAlibaba Cloud Object Storage Serviceにコンテンツをアップロード

このチュートリアルでは、**Node.js**を使って**Webアプリケーション**から**Alibaba Cloud** Object **Storage** Serviceにコンテンツをアップロードする方法を検討します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-to-use-node-js-to-upload-files-to-alibaba-cloud-object-storage_594077)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

#必要条件
このチュートリアルを実行するには、以下のものが必要です。

1、Alibaba Cloud [Object Storage Service](https://www.alibabacloud.com/ja/product/oss)に登録し、秘密のアクセスキーを取得します。
2、マシン上でNode.jsとnpmを実行します。[Node.js Downloads](https://nodejs.org/en/download/?spm=a2c65.11461447.0.0.41786150Cc74CG)には、Nodeのインストール方法についての詳細な情報が記載されています。
まとめると、Alibaba Cloudのアカウント、Object Storage Service、Node.js、npm、OSSサービスのアクセスキーが必要になります。

#アクセスキーをクレデンシャルファイルに追加する方法
そもそも、Alibaba Cloud OSSはRESTfulなAPI操作をサポートしており、ほとんどの言語に対応したSDKを提供しています。このチュートリアルでは、オープンソースのOSS JavaScript SDK for node.jsを使用します。まずはこのように ali-oss をインストールする必要があります。

```
npm install ali-oss
```

注目すべきは、同期モードと非同期モードの2つのモードから選択できることです。

同期モードで使用するには、さらにcoと組み合わせて使用することができます。 coをインストールするようにしてください。

```
npm install co
```
非同期モードはコールバックをサポートしています。

#クライアントの初期化
このメソッドは同期モードで適用されます。このメソッドでは、以下のような app.js オブジェクトを作成します。

```
var co = require('co');
var OSS = require('ali-oss');

var client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>'
});
```

Alibaba Cloudでは、OSSサービスに加入している場合、地域を指定しなければならなかったので、リージョンフィールドは非常に重要です。[OSSノード](https://www.alibabacloud.com/help/ja/doc-detail/31837.htm)の完全なリストは以下の通りです。

さらに、OSS Nodesのリストにないエンドポイントもありますが、その場合は以下のパラメータを設定する必要があります。

1、secure: リージョンと組み合わせて使用します。secureをtrueに指定した場合はHTTPを使ってアクセスします。

2、endpoint: エンドポイントを指定した場合、リージョンを無視しても大丈夫です。endpointにHTTPSを指定してもOKです。

3、bucket:バケットが指定されていない場合は、まず useBucket インターフェースを呼び出す必要があります。

4、timeout: デフォルトでは60秒です。OSS APIのタイムアウトを指定するためのパラメータです。

見た目は問題なさそうですが、次のステップに進みます。

#依存関係のインストール
このステップではnode.jsの依存関係をインストールして、ノードアプリケーションが置かれるディレクトリを作成します。このチュートリアルでは、OSS-node-appで以下のようにアプリを作成します。

```
mkdir sites/OSS-node-app && cd sites/OSS-node-app
```

次に、package.jsonファイルを作成し、そこに以下のコードを貼り付けます。

```
{
  "name": "OSS-node-app",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "license": "MIT"
}
```

上記のサンプルでは、アプリの名前、バージョン、ライセンスを記述した package.json ファイルを作成しています。scriptsパラメータは、node server.jsではなく、npm startを使用してnode serverを実行できるようにします。

インストールする必要のあるすべての依存関係は、npm installコマンドを使用してインストールされます。次に4つの依存関係が続き、このプロジェクトでは以下のようにインストールされます。

```
npm install ali-oss express 
```

私たちの依存関係は、OSSのAPIを使って作業したり、Webサーバーを立ち上げたり、ファイルのアップロードを処理したりすることを可能にしています。上記のコマンドはまた、package.jsonを更新します。

1、ali-OSS - 私たちがJavaScript APIにアクセスできるようにするためのJavaScript用のAlibaba SDKです。
2、express - Expressは、サーバーの迅速かつ効率的なセットアップを可能にします。
プロジェクトの場所と依存関係がすべてセットアップされたので、サーバーを起動してフロントエンドのビューをセットアップすることができます。すべての依存関係は、それ以降のすべてのNode.jsバージョンではデフォルトでpackage.jsonファイルに保存されることに注意してください。

#フロントエンドアプリの作成
アプリケーションのパブリックビュー用のファイルを作成することから始めましょう。index.html、succeed.html、error.htmlを使ってパブリックフォルダを作成します。これら3つのファイルは、以下に示すようなHTMLの骨格を持っていますが、内容が異なるだけです。全てのファイルに以下のコードを貼り付けます。

```
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>OSS Node Tutorial</title>

  <link rel="stylesheet" href="./style.css">
</head>

<body>

  <!—your content here -->

</body>

</html>
```

このように、それぞれのファイルにエラーメッセージを書き込んでください。

```
<h1>Something went wrong!</h1>
<p>Uploading the file was unsuccessful.</p>
```

このように、それぞれのファイルに成功メッセージを書き込んでください。

```
<h1>Success!</h1>
<p>File uploaded successfully.</p>
```

ここでは、index.htmlにmultipart/form-dataを含むHTMLフォームを作成します。フォームには、送信ボタンも用意しなければなりません。

```
<h1>OSS Tutorial</h1>

<p>Please select a file and submit form to upload.</p>

<form method="post" enctype="multipart/form-data" action="/upload">
  <label for="file">Upload a file</label>
  <input type="file" name="upload">
  <input type="submit" class="button">
</form>
```

では、インターフェイスを見やすくするためにstyle.cssを作成します。

```
html {
  font-family: sans-serif;
  line-height: 1.5;
  color: #333;
}

body {
  margin: 0 auto;
  max-width: 500px;
}

label,
input {
  display: block;
  margin: 5px 0;
}
```

無事にアップロード用のファイル、成功ページとエラーページの作成が完了しましたので、弊社のNode.jsアプリをご紹介します。

#Expressを使ったサーバーの設定
今回はExpressフレームワークを使ってnode.jsサーバーを濡らしていきます。まず、プロジェクトのルートディレクトリにserver.jsファイルを作成します。次に、require()を使用して4つの依存関係をロードし、以下のようにExpressのアプリインスタンスを経由してアプリをルーティングする必要があります。

```
server.js
// Load dependencies
const ali = require(ali-oss');
const express = require('express');
const app = express();
```

アプリケーションのフロントエンドは公開リポジトリにあるので、依存関係の設定は以下のように設定しなければなりません。

```
// Views in public directory
app.use(express.static('public'));
```

そして、3つのファイルをサーバのルートに相対的にルーティングするように進めます。

```
// Main, error and success views
app.get('/', function (request, response) {
  response.sendFile(__dirname + '/public/index.html');
});
app.get("/success", function (request, response) {
  response.sendFile(__dirname + '/public/success.html');
});
app.get("/error", function (request, response) {
  response.sendFile(__dirname + '/public/error.html');
});
```

ここでは、リスニングに使用するポートを設定する必要があります。

```
server.js
app.listen(5000, function () {
  console.log('Server listening on port 5000.');
});
```

これを保存して、npm startを使ってサーバーを起動します。

```
npm start
Output
> node server.js
Server listening on port 5000.
```

ブラウザのアドレスバーに**http://localhost:5000**と入力すると、アップロードフォームにアクセスできるはずです。また、**http://localhost:5000/success** と **http://localhost:5000/error** にアクセスして反応を試してみてください。

#ファイルのアップロード
サーバーはすべてセットアップされているので、最初のファイルをAlibaba OSSにアップロードできるようにするために、フォームをali-ossに統合しなければなりません。

```
server.js
const app = express();
// Set endpoint to Alibaba OSS
const spacesEndpoint = new OSS.Endpoint(' http://oss-cn-hangzhou.aliyuncs.com.');
const s3 = new OSS({
  endpoint: spacesEndpoint
});
```

新しい OSS() を使用して OSS クライアントに接続する必要があります。

この最初のインスタンスでは、単純なローカルファイルのアップロードを実装しています。

```
var co = require('co');
var OSS = require('ali-oss')

var client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
});

co(function* () {
  var result = yield client.put('object-key', 'local-file');
  console.log(result);
}).catch(function (err) {
  console.log(err);
});
```

2 番目のインスタンスでは、putStream インターフェイスを使用してアクセスされたストリームのアップロードを使用します。固有の読み取り可能なストリームを持つ任意のオブジェクトは、このメソッドで有効になります（オブジェクトとネットワーク ストリームの両方）。putStream インターフェースが使用されると、SDK は自動的にチャンク化されたエンコーディングの HTTP PUT を開始します。

```
var co = require('co');
var OSS = require('ali-oss');
var fs = require('fs');

var client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
});

co(function* () {
  // use 'chunked encoding'
  var stream = fs.createReadStream('local-file');
  var result = yield client.putStream('object-key', stream);
  console.log(result);

  // do not use 'chunked encoding'
  var stream = fs.createReadStream('local-file');
  var size = fs.statSync('local-file').size;
  var result = yield client.putStream(
    'object-key', stream, {contentLength: size});
  console.log(result);
}).catch(function (err) {
  console.log(err);
});
```

バッファ内のオブジェクトの内容をアップロードするには、put インターフェースを介してアクセスします。

```
var co = require('co');
var OSS = require('ali-oss');

var client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
});

co(function* () {
  var result = yield client.put('object-key', new Buffer('hello world'));
  console.log(result);
}).catch(function (err) {
  console.log(err);
});
```

非常に大きなファイルをアップロードする場合、multipartUploadインターフェースはリクエストをより小さな実行可能なリクエストに分割することができます。この方法の利点は、ファイル全体を修正するのとは対照的に、失敗した部分だけをアップロードする必要があることです。以下のパラメータを使用します。

1、name {String}:オブジェクト名
2、file  {String|File}:ファイルパスまたは HTML5 Web ファイル
3、[options] {Object}:オプションのパラメータ

1、[checkpoint] {Object}: 再開可能なアップロードで使用するエンドポイントのチェックポイントです。このパラメータを設定すると、エンドポイントからアップロードが開始されます。設定されていない場合は、アップロードを再開します。
2、[partSize] {Number}: パーツサイズ
3、[progress] {Funtion}: ジェネレーター機能。3つのパラメータを含む。
-----1.(percentage {Number}: アップロードの進捗状況 (0から1までの10進数)
-----2.(checkpoint {Object}.:エンドポイントチェックポイント
-----3.(res {Object}):単一のパーツが正常にアップロードされた後に返されるレスポンス
4、[meta] {Object}: x-oss-meta-という接頭辞を持つユーザによって定義されたヘッダメタ情報。
5、[headers] {Object}: 余分なヘッダ。詳細は RFC 2616 を参照してください。
-----1.'Cache-Control':HTTP リクエストとレスポンスでコマンドを指定してキャッシュメカニズムを実装するために使用される一般的なヘッダ。例えば、以下のようになります。Cache-Control: public, no-cache
-----2.'Content-Disposition':これは、内部参照(ウェブページやページの一部)や、ローカルにダウンロードして保存された添付ファイルである可能性があります。例えば、以下のようになります。Content-Disposition: somename
-----3.'Content-Encoding':特定のメディアタイプのデータを圧縮するために使用されます。例えば Content-Encoding: gzip
-----4.'Expires':有効期限。例えば Expires. 3600000

```
var co = require('co');
var OSS = require('ali-oss')

var client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
});

co(function* () {
  var result = yield client.multipartUpload('object-key', 'local-file', {
    progress: function* (p) {
      console.log('Progress: ' + p);
    }
 meta: {
      year: 2017,
      people: 'test'
    }
  });
  console.log(result);
  var head = yield client.head('object-key');
  console.log(head);
}).catch(function (err) {
  console.log(err);
});
```

上記のprogressパラメータは、アップロードの進捗状況を取得するためのcalback関数です。

```
var progress = function (p) {
  return function (done) {
    console.log(p);
    done();
  };
};
```

#結論
おめでとうございます。Alibaba Cloud [Object Storage Service (OSS)](https://www.alibabacloud.com/ja/product/oss) スペースにオブジェクトをアップロードするためのExpressアプリケーションの設定に成功しました! Alibaba Cloudのアカウントをお持ちでない方は、アカウントを登録してください。アカウントにサインアップして、最大1200ドル相当の[40以上の製品を無料で](https://www.alibabacloud.com/ja/campaign/free-trial)お試しください。Alibaba Cloudの詳細については、「[Get Started with Alibaba Cloud](https://www.alibabacloud.com/ja/getting-started)」を参照してください。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*