Uploading Image to Amazon s3 with HTML, javascript & jQuery with Ajax Request (No PHP)

JavascriptHtmlJqueryAmazon S3

Javascript Problem Overview


I am developing a website in HTML, javascript & jQuery. I want to upload images to amazon s3 server in an ajax request. There is no such SDK to integrate s3 in Javascript. A PHP SDK is available, but it is not useful to me. Can anybody provide solution to this in javascript?

Javascript Solutions


Solution 1 - Javascript

Got Amazon S3 & CORS working on js and html5 using XMLHTTPObject based on this article article.

1: CORS only works from a proper URL "http://localhost";. (file///xyz will make you go insane)

2 : Make sure you got the POLICY and Secret compiled correctly - here is my policy and this is the link you can get the project to get you started with Signature and Policy -- do not publish this JS with your Secret EVER!

POLICY_JSON = { "expiration": "2020-12-01T12:00:00.000Z",
		    "conditions": [
			{"bucket": this.get('bucket')},
			["starts-with", "$key", ""],
			{"acl": this.get('acl')},							
			["starts-with", "$Content-Type", ""],
			["content-length-range", 0, 524288000]
		    ]
		  };


    var secret = this.get('AWSSecretKeyId');
    var policyBase64 = Base64.encode(JSON.stringify(POLICY_JSON));
    console.log ( policyBase64 )

    var signature = b64_hmac_sha1(secret, policyBase64);
    b64_hmac_sha1(secret, policyBase64);
    console.log( signature);

Here is the JS code

function uploadFile() {
    
    var file = document.getElementById('file').files[0];
    var fd = new FormData();
          
    var key = "events/" + (new Date).getTime() + '-' + file.name;

    fd.append('key', key);
    fd.append('acl', 'public-read'); 
    fd.append('Content-Type', file.type);      
    fd.append('AWSAccessKeyId', 'YOUR ACCESS KEY');
    fd.append('policy', 'YOUR POLICY')
    fd.append('signature','YOUR SIGNATURE');
    
    fd.append("file",file);

    var xhr = new XMLHttpRequest();

    xhr.upload.addEventListener("progress", uploadProgress, false);
    xhr.addEventListener("load", uploadComplete, false);
    xhr.addEventListener("error", uploadFailed, false);
    xhr.addEventListener("abort", uploadCanceled, false);
    
    xhr.open('POST', 'https://<yourbucket>.s3.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND 
   
    xhr.send(fd);
  }

Helper functions

function uploadProgress(evt) {
    if (evt.lengthComputable) {
      var percentComplete = Math.round(evt.loaded * 100 / evt.total);
      document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
    }
    else {
      document.getElementById('progressNumber').innerHTML = 'unable to compute';
    }
  }

  function uploadComplete(evt) {
    /* This event is raised when the server send back a response */
    alert("Done - " + evt.target.responseText );
  }

  function uploadFailed(evt) {
    alert("There was an error attempting to upload the file." + evt);
  }

  function uploadCanceled(evt) {
    alert("The upload has been canceled by the user or the browser dropped the connection.");
  }

Then the HTML Form

 <form id="form1" enctype="multipart/form-data" method="post">
<div class="row">
  <label for="file">Select a File to Upload</label><br />
  <input type="file" name="file" id="file" onchange="fileSelected()"/>
</div>
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
<div class="row">
  <input type="button" onclick="uploadFile()" value="Upload" />
</div>
<div id="progressNumber"></div>

Happy CORS-ing!

Solution 2 - Javascript

Amazon just allowed Cross-Origin Resource Sharing, in theory it allows your users to upload to S3 directly, without using your server (and PHP) as a proxy.

Heres the docs -> http://docs.amazonwebservices.com/AmazonS3/latest/dev/cors.html

They do a great job of telling you how to enable it on an S3 bucket, but iv found no actual javascript examples of how to get data from client to bucket.

First person to post CORS.js is a legend xD

Solution 3 - Javascript

Here's an example of resumable file uploads on Amazon S3 using CORS and javascript http://cotag.github.com/Condominios/

Solution 4 - Javascript

You can do this by AWS S3 Cognito try this link here :

http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-examples.html#Amazon_S3

Also try this code

Just change Region, IdentityPoolId and Your bucket name

<!DOCTYPE html>
<html>

<head>
    <title>AWS S3 File Upload</title>
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js"></script>
</head>

<body>
    <input type="file" id="file-chooser" />
    <button id="upload-button">Upload to S3</button>
    <div id="results"></div>
    <script type="text/javascript">
    AWS.config.region = 'your-region'; // 1. Enter your region
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: 'your-IdentityPoolId' // 2. Enter your identity pool
    });
    AWS.config.credentials.get(function(err) {
        if (err) alert(err);
        console.log(AWS.config.credentials);
    });
    var bucketName = 'your-bucket'; // Enter your bucket name
    var bucket = new AWS.S3({
        params: {
            Bucket: bucketName
        }
    });
    var fileChooser = document.getElementById('file-chooser');
    var button = document.getElementById('upload-button');
    var results = document.getElementById('results');
    button.addEventListener('click', function() {
        var file = fileChooser.files[0];
        if (file) {
            results.innerHTML = '';
            var objKey = 'testing/' + file.name;
            var params = {
                Key: objKey,
                ContentType: file.type,
                Body: file,
                ACL: 'public-read'
            };
            bucket.putObject(params, function(err, data) {
                if (err) {
                    results.innerHTML = 'ERROR: ' + err;
                } else {
                    listObjs(); // this function will list all the files which has been uploaded
                    //here you can also add your code to update your database(MySQL, firebase whatever you are using)
                }
            });
        } else {
            results.innerHTML = 'Nothing to upload.';
        }
    }, false);
    function listObjs() {
        var prefix = 'testing';
        bucket.listObjects({
            Prefix: prefix
        }, function(err, data) {
            if (err) {
                results.innerHTML = 'ERROR: ' + err;
            } else {
                var objKeys = "";
                data.Contents.forEach(function(obj) {
                    objKeys += obj.Key + "<br>";
                });
                results.innerHTML = objKeys;
            }
        });
    }
    </script>
</body>

</html>

If needed you can use github Link

I hope it will help others :)

Solution 5 - Javascript

For the authentication part,

No php code, no server, no large JS code except below;

you might use AWS Cognito IdentityPoolId as credential, less code but you are required to create AWS Cognito IdetityPool and attach policy, simply s3 write access.

var IdentityPoolId = 'us-east-1:1...........';

 AWS.config.update({
    credentials: new AWS.CognitoIdentityCredentials({
	    IdentityPoolId: IdentityPoolId
    })
 });
		

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSwapnil GodambeView Question on Stackoverflow
Solution 1 - JavascriptfinoView Answer on Stackoverflow
Solution 2 - JavascriptlukejacksonnView Answer on Stackoverflow
Solution 3 - JavascriptPaddlePoPView Answer on Stackoverflow
Solution 4 - JavascriptJoomlerView Answer on Stackoverflow
Solution 5 - JavascriptMustafa KahramanView Answer on Stackoverflow