AWS SDK with Javascript: Upload File to S3
Tags: aws, javascript, upload, file
Published: 2021-06-26 10:50:31

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](https://dev.to/ldsrogan/aws-sdk-with-javascript-download-file-from-s3-el2)



## 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](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html).

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

*Policy*
```json
"s3:PutObject",
"s3:ListBucket",
```
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*
```json
 "AllowedMethods": [
            "PUT",
            "POST",
        ],
```

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.
```bash
npm install aws-sdk
```

And here is the simple code to generate the upload URL.
First, you need to create S3 bucket object.
```javascript
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
});
``` 

And then, use `getSignedUrlPromise()` to receive the generated upload URL.
```javascript
 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);
    });
```

Once, you received the URL, you can use the HTTP request module (in my case, I used axios) to upload the file.
```javascript
// 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);
      });

```
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).