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 Javascrip
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 }) });
Here's an example of resumable file uploads on Amazon S3 using CORS and javascript http://cotag.github.com/Condominios/
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
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!
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 :)