DEV Community

Shin-Young Jung
Shin-Young Jung

Posted on

AWS SDK with Javascript: Upload File to S3

This is the second article about using AWS SDK in JavaScript to upload files to S3.
If you are interested in the previous article, please checkout the following link.

AWS-SDK Download File From S3

Initial Setup in AWS

please make sure that you have AWS account with admin authority.

After you logged in AWS, you should create a policy, attach it to your account, and then create an access key.

I'm not going to talk about all the detail of how to set up for AWS, so if you want to know how to do this, please refer to the AWS Official Documentation.

And When you create a policy for file uploading, you should include the following.

Policy

"s3:PutObject",
"s3:ListBucket",
Enter fullscreen mode Exit fullscreen mode

Also, in order to allow others to access your S3 files with the generated URL, you need to set up the CORS policy in the permission tab of your S3 Bucket.

CORS policy

 "AllowedMethods": [
            "PUT",
            "POST",
        ],
Enter fullscreen mode Exit fullscreen mode

Now, it's ready to access S3 from the code base and upload files.

Upload File In Javascript Code Base

Once you received the AWS access key and secret key, you can store them with AWS region info and bucket name in the .env file.

Also, please make sure that you installed aws-sdk in your project.
To install aws-sdk, you can simply use npm package manager to do below.

npm install aws-sdk
Enter fullscreen mode Exit fullscreen mode

And here is the simple code to generate the upload URL.
First, you need to create S3 bucket object.

const s3bucket = new AWS.S3({
  accessKeyId: process.env.AWS_ACCESS_KEY,
  secretAccessKey: process.env.AWS_SECRET_KEY,
  signatureVersion: 'v4',
  region: process.env.AWS_REGION, // ex) us-west-2
});
Enter fullscreen mode Exit fullscreen mode

And then, use getSignedUrlPromise() to receive the generated upload URL.

 const params = {
    Bucket: process.env.AWS_BUCKET_NAME,
    Expires: 3000, // expire time in second
    Key, // this key is the S3 full file path (ex: mnt/sample.txt)
  };

// notice that this is the same method that we used for downloading, 
// but using 'putObject' instead of 'getObject'
  const url = await s3bucket
    .getSignedUrlPromise('putObject', params)
    .catch((err) => {
      logger.error(err);
    });
Enter fullscreen mode Exit fullscreen mode

Once, you received the URL, you can use the HTTP request module (in my case, I used axios) to upload the file.

// create read stream with file's full path including file name and extension
const istream = fs.createReadStream(streamPath);

// using generated uploading url to upload file
    axios.put(url, istream, {
        headers: {
          'Content-Type': mimetype, // mime type of the file
          'Content-Length': totalSize, // file's total size
        },
      }).then(() => {
        console.log('http upload success!');
      }).catch((err) => {
        console.error(err);
      });

Enter fullscreen mode Exit fullscreen mode

with the read stream object, you can follow events with .on() function. The events that you may be interested in during the upload are close (when the stream is finished, meaning upload is done), data(sending data chunk - upload process), and error (when failed to upload).

Top comments (0)