通常、ファイルのアップロードはアプリケーションサーバーを経由してストレージに保存されます。しかし、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トークンを使用するように構成します。