AWS_SDKでS3にアップした画像を開くとブラウザに表示されないあなたへ

More than 3 years have passed since last update.


Node.jsから画像のアップ

という機能作った時にハマった話

コードはこんな感じ

var

AWS = require('aws-sdk'),
fs = require('fs'),
upload;

AWS.config.update({
accessKeyId: 'AKIXXXXXXXXXXXXX',
secretAccessKey: 'XXXXXXXXXXXXXXXXXXXXXX',
region: 'ap-northeast-1'
});

upload = function ( file, callback ) {
var
bucketName = "hogehogeBucket",
fileName = file.filename,
body = fs.readFileSync(file.path),
s3 = new AWS.S3({params: {Bucket: bucketName, Key: fileName}});

s3.upload({Body: body}, function(evt) {
// console.log(evt);
}).send(function(err, data) {
// 結果返す
callback(err, data);
});

};

module.exports = {
upload : upload
};

画像はアップできるんだけど、アップしたファイルのURLにアクセスすると、ブラウザに画像が表示されるわけでなく…

スクリーンショット 2016-06-17 15.12.04.png

こんな感じでブラウザがダウンロード開始しちゃう。

違うんだよ!保存じゃなくてブラウザに表示さえしてくれればいいんだよ!という気持ちになる。

Qiitaの画像なんかは同じくs3の画像だけど、開くとブラウザに表示される。

何が違うんだ!


Content-Typeを指定してなかった

AWSのマネジメントコンソールで手作業でアップした画像ファイルはブラウザで表示できた。

aws-sdkから上げたファイルとオブジェクトのプロパティ見比べてみるとここが違った


  • 手作業で上げたjpegファイル

スクリーンショット 2016-06-17 15.26.37.png


  • aws-sdkで上げたjpegファイル

スクリーンショット 2016-06-17 15.30.44.png

Content-Typeがoctet-streamになっとる。content-typeを指定するパラメータが抜けてたのね。


これでOK

s3.upload関数の引数にContentTypeパラメータを指定してやる

var

AWS = require('aws-sdk'),
fs = require('fs'),
upload;

AWS.config.update({
accessKeyId: 'AKIXXXXXXXXXXXXX',
secretAccessKey: 'XXXXXXXXXXXXXXXXXXXXXX',
region: 'ap-northeast-1'
});

upload = function ( file, callback ) {
var
bucketName = "hogehogeBucket",
fileName = file.filename,
body = fs.readFileSync(file.path),
s3 = new AWS.S3({params: {Bucket: bucketName, Key: fileName}});
// ★ ↓この部分 ★
s3.upload({Body: body, ContentType: file.mimetype}, function(evt) {
// console.log(evt);
}).send(function(err, data) {
// 結果返す
callback(err, data);
});

};

module.exports = {
upload : upload
};

情報探しても意外と出てこなかったけどこれって常識?探し方が悪かったのかなあ


ちなみに

上の関数を他から呼び出すなら

var s3 = require( './lib/s3' );

s3.upload( req.file, function (err, data) {
// なんか処理
}

的な感じで使えます。(上記のモジュールはlib/s3.jsとして保存)

引数のreq.fileはmulterと言うExpressのパッケージを使って取れるものです。