ブラウザからOSSへ直接ファイルをアップロードする実装ガイド

通常、ファイルのアップロードはアプリケーションサーバーを経由してストレージに保存されます。しかし、Alibaba Cloud OSS(Object Storage Service)などのクラウドストレージを利用する場合、ブラウザから直接OSSへアップロードする「ダイレクトアップロード」を採用することで、多くのメリットを享受できます。

ダイレクトアップロードを採用する利点

  • パフォーマンスの向上: アプリサーバーを経由しないため、ネットワークの転送回数が減り、アップロード速度が向上します。OSSのBGP帯域を利用することで、安定した高速通信が期待できます。
  • スケーラビリティの確保: 大容量ファイルの処理や大量の同時接続によるサーバー負荷を回避でき、リソースのボトルネックを解消できます。
  • コストの削減: OSSへのデータ転送(インバウンド)は基本的に無料です。アプリサーバーの帯域消費を抑えることで、サーバーコストを最適化できます。

OSS SDKの導入と初期設定

SDKをプロジェクトに導入する際、環境によってはモジュールのインポートで問題が発生することがあります。その場合は、CDN経由でスクリプトを読み込む手法が確実です。以下は、一時的な認証情報(STS)を利用したクライアントの初期化例です。

// OSSクライアントの初期化
const ossClient = new OSS.Wrapper({
  region: 'oss-cn-hangzhou', // リージョン
  accessKeyId: config.AccessKeyId, // STSアクセスキーID
  accessKeySecret: config.AccessKeySecret, // STSアクセスキーシークレット
  stsToken: config.SecurityToken, // セキュリティトークン
  bucket: 'your-bucket-name', // バケット名
  secure: true // HTTPSを有効にする
});

/**
 * ファイルのアップロード実行
 * @param {string} fileName 保存名
 * @param {Buffer} data アップロードするデータ
 */
const performUpload = (fileName, data) => {
  const targetPath = `uploads/${Date.now()}_${fileName}`;
  
  ossClient.put(targetPath, data)
    .then(result => {
      console.log('アップロード成功:', result);
    })
    .catch(error => {
      console.error('アップロードエラー:', error);
    });
};

画像の圧縮とデータ変換

Webブラウザで画像を扱う場合、Canvas APIを使用してリサイズや圧縮を行うのが一般的です。OSSのputメソッドでBlobを直接扱えない場合は、ArrayBufferを経由してOSS.Bufferへ変換する必要があります。

/**
 * 画像ファイルを圧縮し、アップロード可能なBuffer形式に変換する
 * @param {File} file 対象ファイル
 * @param {number} quality 圧縮品質 (0.1 - 1.0)
 * @param {function} callback 変換後の処理
 */
function processAndCompressImage(file, quality, callback) {
  const reader = new FileReader();
  
  reader.onload = (e) => {
    const img = new Image();
    img.onload = () => {
      // Canvasを利用したリサイズ処理
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      canvas.width = img.width;
      canvas.height = img.height;
      ctx.drawImage(img, 0, 0);

      // Blobへ変換(圧縮適用)
      canvas.toBlob((blob) => {
        const bufferReader = new FileReader();
        bufferReader.onload = (event) => {
          // OSS SDKで使用可能なBuffer形式に変換
          const ossBuffer = new OSS.Buffer(event.target.result);
          callback(ossBuffer);
        };
        bufferReader.readAsArrayBuffer(blob);
      }, 'image/jpeg', quality);
    };
    img.src = e.target.result;
  };
  
  reader.readAsDataURL(file);
}

// 実行例
const handleFileSelect = (event) => {
  const file = event.target.files[0];
  processAndCompressImage(file, 0.7, (readyBuffer) => {
    performUpload(file.name, readyBuffer);
  });
};

実装上の注意点

OSSへブラウザから直接アクセスする場合、バケットのCORS(Cross-Origin Resource Sharing)設定が不可欠です。許可するメソッド(PUT, POSTなど)やヘッダーを適切に設定してください。また、セキュリティの観点から、固定のAccessKeyを使用するのではなく、必ずサーバーサイドで発行した有効期限付きのSTSトークンを使用するように構成します。

タグ: OSS javascript Aliyun ImageCompression WebDevelopment

10月20日 19:20 投稿