Uploading files to Amazon S3 directly from the front-end using JavaScript AWS SDK on a Django web application

I am working on a Django app and trying to upload files in the front end to bypass Heroku's timeout. However, I am struggling to get my code to function correctly.

<script type="text/javascript">
         AWS.config.update({
            region: 'us-east-1',
            credentials: new AWS.CognitoIdentityCredentials({
            IdentityPoolId: 'MY-IDENTITY-POOL-ID',
            })
        });

        var s3 = new AWS.S3({
            apiVersion: '2006-03-01',
            params: {Bucket: 'MYBUCKETNAME'}
    });
    <script type="text/javascript">

  function s3upload() { 
            var files = document.getElementById('fileUpload').files;
            if (files) 
            {
                var file = files[0];
                var fileName = file.name;
                var fileUrl = 'https://' + 'MYBUCKETNAME.s3.' + 'us-east-1' + '.amazonaws.com/' +  fileName;
                alert(fileUrl)

                var s3 = new AWS.S3({
                    apiVersion: '2006-03-01',
                    params: {Bucket: 'MYBUCKETNAME'}
                });          
                s3.upload({
                        Key: fileName,
                        Body: file,
                        ACL: 'public-read'
                    }, function(err, data) {
                        if(err) {
                            reject('error');
                        }
                        alert('Successfully Uploaded!');
                    });
            }
  };
</script>

I am aware that there might be an issue with how I am passing variables to the AWS API as this is my first time using this method. Can someone guide me on the correct way to structure the API variables above? The documentation available is quite confusing.

Answer №1

I managed to successfully implement my code using the following approach:

    <script type="text/javascript">

  function uploadToS3() { 
    AWS.config.region = 'us-east-1'; // Region
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: 'My-CREDITIONALS',
    });

    var files = document.getElementById('fileUpload').files;
    if (files) 
    {
        var file = files[0];
        var fileName = file.name;
        var fileUrl = 'https://MY-BUCKET-NAME.s3.amazonaws.com/' + fileName;

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

        var params = {
            Bucket: 'MY-BUCKET',
            Key: fileName,
            Body: file,
        };

        var s3 = new AWS.S3({apiVersion: '2006-03-01'});  
        var options = {partSize: 5 * 1024 * 1024, queueSize: 1};

        s3.upload(params, options, function(err, data) {
                if(err) {
                    alert('error');
                } else{
                alert('uploaded suceessfully')
                };
        });
        console.log(s3)

    }
  };
</script>

For larger files over 40MB, I am currently working on enhancing the functionality to support such files.

Update: The issue with uploading large files was due to missing ETag in my CORS policy for multipart uploads. Now, it can handle files up to 470MB at a rate of about 1.5MB per second. A random integer is added to the URL to prevent naming conflicts caused by spaces, commas, and special characters like currency symbols.

    <div>
    <input type="file" id="fileUpload">
</div>

<div>
<button onclick="uploadToS3()">Submit</button>
</div>



<script type="text/javascript">

  function uploadToS3() { 
    AWS.config.region = 'us-east-1'; // Region
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: 'MY-CREDENTIALS',
    });

    var files = document.getElementById('fileUpload').files;
    if (files) 
    {
        var file = files[0];
        var fileNameAllChars = file.name;
        var fileName = fileNameAllChars.replace(/\W/g, '')
        var random = Math.floor(Math.random() * 101)
        var fileUrl = 'https://MY-BUCKET.s3.amazonaws.com/' + fileName + random;
        alert(fileUrl)

        var s3 = new AWS.S3({apiVersion: '2006-03-01', Bucket: 'MY-BUCKET'}); 

        var params = {
            Bucket: 'MY-BUCKET',
            Key: fileName,
            Body: file,
        };

        var s3 = new AWS.S3({apiVersion: '2006-03-01'});  
        var options = {partSize: 15 * 1024 * 1024, queueSize: 1};

 
        s3.upload(params, options, function(err, data) {
                if(err) {
                    alert(err);
                } else{
                alert('success')
                };
        });
        console.log(s3)


    }
  };
</script>

Remember to include the JavaScript AWS SDK in the HTML header:

<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

Unfortunately, this code does not function properly in production environments. The JavaScript AWS SDK also exceeds Heroku's 30-second timeout limit. As a result, I have developed a custom solution based on the above code. I will upload that solution later since I am currently unable to do so from my phone.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Methods for delivering static resources on multiple routes in Express JS

Is there a way to effectively serve static resources for all routes in Express JS? I attempted to serve files with static resources using the following code snippet: app.use(Express.static(`${this.PATH}`)); app.use(Cors()); app.use(Express.json()); app.g ...

Utilizing Twitter Bootstrap to populate form fields from a dropdown selection

I am currently using twitter bootstrap for my front end web development project. I have successfully implemented a text field with a dropdown menu right next to it: <div class="input-group"> <input type="text" class="form-control" name="ope ...

Error: ExecJS encountered a problem when attempting to run the code in this ChatRooms

The problem at hand: This is my room.coffee file, and everything is functioning correctly. jQuery(document).on 'turbolinks:load', -> messages = $('#messages') if $('#messages').length > 0 App.global_chat = A ...

CFGRID Binding Issue: Element Not Located in CF11 Compared to CF2018

After spending some time tinkering with this issue, I finally found a solution that worked for me. I decided to share it here in the hopes that it might help others save some time. In ColdFusion 11, my binding parameter looked like this: <cfset args.b ...

I'm having trouble getting the npm install for classnames to work within my li tag

I need some help with React JS. I'm attempting to merge my classes using the npm package called classnames. https://www.npmjs.com/package/classnames However, I'm encountering an issue: classnames doesn't seem to be working as expecte ...

Using Node.js variables outside of a function

I've been facing issues with passing my trends variable from its function into a renderer for my Pug template. It's proving to be quite challenging. var express = require('express'); ...

Ways to recycle a section of Javascript for multiple uses on a single page

As a newcomer to website building, I have a query regarding the usage of a JavaScript function designed for a slideshow. My one-page website comprises multiple slideshow units with their own divs, holders, and counters (e.g., 1/4). A JavaScript code contro ...

Loop through a collection of objects and combine their values

I'm struggling with what seems like a basic issue. I have an array that looks like this: var myArray = [{a:3, b:4, c:5}, {a:-1, b:3, c:5}, {a:0, b:-3, c:1}]; I need to create a loop to add up all the values for 'a', 'b', and &apo ...

Navigating to a new page once a backend function in Express has finished executing

Recently, I have been experimenting with express web servers to create a website that allows users to sign in using Discord's OAuth2 API. In order to secure sensitive information, I have been utilizing the express-session npm module to store data with ...

What is the best way to retrieve the overall error status from the Material UI DataGrid?

I am currently utilizing the Material UI DataGrid element to display information from an EXCEL file. Each Excel document consists of numerous column titles with specific types assigned to them. As an example: const columns = [ { "field&quo ...

Tips on organizing JSON data with JavaScript

After receiving my $http response, the data is presented in the format below: $scope.rooms = { '2B' : [ {"RoomEmailId":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ebd9a9c6d8d9d8ab868ec5888486" ...

The return value from vue-query is ObjectRefImpl, not the actual data

Greetings to the Vue.js community! As a newcomer to Vue.js, I am seeking guidance on fetching data using vue-query, Vue.js 3, and the composition API. The data returned to me is ObjectRefImpl, but when I try to print the values, I encounter the error: "Pro ...

Modify components in a web application based on the content of a JavaScript variable

I'm in the process of developing a webapp that needs to interact with an Arduino for its inputs in order to dynamically change the contents of the webpage. Currently, I am experimenting with variables that I have created and assigned random numbers t ...

Mysterious Source within AngularJS $resource

I have been encountering the error of unknown provider, and have explored various solutions but I feel like there is something missing: app.js var myApp = angular.module('myApp', [ 'ngResource', 'myAppControllers', ...

Switching the background image when hovering over a list element

Looking at the screenshot, it's clear that there is an unordered list with a background image set on the div. What I am trying to achieve is to have the background image change whenever I hover over a list item. Each list item should trigger a differe ...

"Exploring the power of Nextjs Server-Side Generation with 10 million

I am working on a Next.js application that utilizes an API to fetch 10 million posts. I am considering using the SSG method for this purpose, but I am unsure if it is the standard approach. Additionally, I may need to add new posts dynamically in the fut ...

Creating a JSON object using various inputs through AngularJS

Just starting out with Ionic, Angular, and Firebase. This might be a silly question :) I'm working on an app using Ionic + Firebase, and I want to create a JSON object from multiple inputs. The interface looks like the image below: https://i.stack.i ...

Obtain the current date using Moment JS in JavaScript

Here is a scenario with code : let currentTime = moment(); console.log(currentTime.format()); // 2019-11-25T20:23:50+02:00 console.log(currentTime.toDate()); // 2019-11-25T18:23:50.916Z After applying the timezone change on Heroku using the command ...

What is the best way to transmit a JavaScript array using Ajax?

Is there a way to send an array instead of just string or numeric values? ...

Retrieve the array from the response instead of the object

I need to retrieve specific items from my database and then display them in a table. Below is the SQL query I am using: public async getAliasesListByDomain(req: Request, res: Response): Promise<void> { const { domain } = req.params; const a ...