How do I set my images uploaded to S3 with nodejs script to display instead of download?

Viewed 1089

I have a node js script that uploads files to AWS S3 through the command line. The problem Im having is when I try to view the file in the browser it automatically downloads it.

I have done some research and most other posts point out the headers, but I have verified the headers are correct (image/png)

Additionally, when I upload the same file through the AWS console (log into AWS), I am able to view the file within the browser.

var fs = require('fs');
var path = require('path');

AWS.config.update({region: myRegion});

s3 = new AWS.S3({apiVersion: '2006-03-01'});

var uploadParams = {
    Bucket: process.argv[2],
    Key: '', // Key set below
    Body: '', // Body set below after createReadStream
    ContentType: 'image/jpeg',
    ACL: 'public-read',
    ContentDisposition: 'inline'
};
var file = process.argv[3];

var fileStream = fs.createReadStream(file);
fileStream.on('error', function(err) {
  console.log('File Error', err);
});

uploadParams.Body = fileStream;
uploadParams.Key = path.basename(file);


s3.putObject(uploadParams, function(errBucket, dataBucket) {
    if (errBucket) {
      console.log("Error uploading data: ", errBucket);
    } else {
      console.log(dataBucket);
    }
  });

I get successful upload, but unable to view file in browser as it auto downloads.

2 Answers

You have to specify the contentDisposition as part of request headers. You can not specify it as part of request paramenters. Specify it in headers explicitly as below .

var params = {Bucket : "bucketname" , Key : "keyName" , Body : "actualData"};
s3.putObject(params).
on('build',function(req){
req.httpRequest.headers['Content-Type'] = 'application/pdf' ; // Whatever you want
req.httpRequest.headers['ContentDisposition'] = 'inline';   
}).
send( function(err,data){
    if(err){
    console.log(err);
    return res.status(400).json({sucess: false});
    }else{
    console.log(success);
    return res.status(200).json({success: true});
    }
});  

Code to upload obejcts/images to s3

module.exports = function(app, models) {

    var fs = require('fs');
    var AWS = require('aws-sdk');
    var accessKeyId =  "ACESS KEY HERE";
    var secretAccessKey = "SECRET KEY HERE";

    AWS.config.update({
        accessKeyId: accessKeyId,
        secretAccessKey: secretAccessKey
    });

    var s3 = new AWS.S3();

    app.post('/upload', function(req, res){

        var params = {
            Bucket: 'bucketname',
            Key: 'keyname.png',
            Body: "GiveSomeRandomWordOraProperBodyIfYouHave"
        };

        s3.putObject(params, function (perr, pres) {
            if (perr) {
                console.log("Error uploading data: ", perr);
            } else {
                console.log("Successfully uploaded data to myBucket/myKey");
            }
        });
    });

}

The above code will make sure the object has been uploaded to s3. You cab see it listed in s3 bucket in the browser but you cant view its contents in s3 bucket.

You can not view items within S3. S3 is a storage box. you can only download and upload elements in it. If you need to view the contents you would have to download and view it in the browser or any explorer of your choice. If you simply need to list the objects in s3. Use the below code.

Code to list objects of s3

var AWS = require('aws-sdk');
AWS.config.update({accessKeyId: 'mykey', secretAccessKey: 'mysecret', region: 'myregion'});
var s3 = new AWS.S3();

var params = { 
 Bucket: 'bucketName',
 Delimiter: '/',
 Prefix: 's/prefix/objectPath/'
}


s3.listObjects(params, function (err, data) {
 if(err)throw err;
 console.log(data);
});

Use S3 list to list the elements of S3. This way you can view them. Create a hyperlink for each of the listed item and make it point to s3 download url. This way you can view in the browser and also download it if you need.

In case if you need to view the contents of it via node JS, use the code below to load the image as if you are loading it from a remote URL.

Code to Download contents:

var fs = require('fs'),
    request = require('request');

var download = function(uri, filename, callback){
  request.head(uri, function(err, res, body){
    console.log('content-type:', res.headers['content-type']);
    console.log('content-length:', res.headers['content-length']);

    request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
  });
};

download('httpo://s3/URL' 'name.png', function(){
  console.log('done');
});

Code to load image into a buffer :

const request = require('request');

let url = 'http://s3url/image.png';
request({ url, encoding: null }, (err, resp, buffer) => {
     // typeof buffer === 'object'
     // Use the buffer
     // This buffer will now contains the image data

});

Use the above to load the image into a buffer. Once its in buffer, you can manipulate it the way you need. The above code wont downloads the image but it help you to manipuate the image in s3 using a buffer.

Contains Example Code. The link will contain Specific Node JS code examples for uploading and Manipulating objects of s3. use it for reference.

Related