Skip to content

Instantly share code, notes, and snippets.

@adrichman
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adrichman/e550885f6011f37d6bd3 to your computer and use it in GitHub Desktop.
Save adrichman/e550885f6011f37d6bd3 to your computer and use it in GitHub Desktop.
S3 form-data upload - receives freshly signed policy from ZipClips API, then callback commences direct upload to AWS S3 with credentials
var AWS = require('aws-sdk');
var fs = require('fs');
var crypto = require("crypto");
AWS.config.update({region: 'us-west-2', accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY});
// SEE: http://stackoverflow.com/questions/18476217/amazon-s3-post-api-and-signing-a-policy-with-nodejs
exports.createS3Policy = function(key, callback) {
var date = new Date(Date.now() + 300000);
var s3Policy = {
"expiration": date,
"conditions": [
{"bucket": "zipclips"},
["starts-with", "$key", key],
{"acl": "public-read"},
["starts-with", "$Content-Type", "multipart/form-data"],
["content-length-range", 0, 524288000]
]
};
////////////////////////////////////
// stringify and encode the policy//
////////////////////////////////////
var stringPolicy = JSON.stringify(s3Policy);
var base64Policy = Buffer(stringPolicy, "utf8").toString("base64");
////////////////////////////////////
// sign the base64 encoded policy //
////////////////////////////////////
var signature = crypto.createHmac("sha1", process.env.AWS_SECRET_ACCESS_KEY)
.update(new Buffer(base64Policy, "utf8")).digest("base64");
////////////////////////////////////
// build the results object //
////////////////////////////////////
var s3Credentials = {
s3Policy: base64Policy,
s3Signature: signature
};
callback(s3Credentials);
};
<!DOCTYPE html>
<html>
<head>
<title>Upload to S3</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
</head>
<body>z
<form action="" enctype="multipart/form-data" method="PUT" id="uploadForm">
<input type="file" name="file" id="file">
<input type="hidden" name="url" id="url" value="http://testUrl.com">
<button type="submit" id="btn_submit">Submit</button>
</form>
<progress value="0" max="100"></progress>
<div id="status"></div>
<script>
$(document).on('ready', function(){
var uploadUrl = "";
var name = "";
var file = $('#file');
$('#btn_submit').on('click', function(e){
e.preventDefault();
var name = $('#file').val().split('\\')[2];
var data = {
Bucket:'your-bucket',
Key: 'uploads\/' + name,
ACL: 'public-read',
ContentType: 'multipart/form-data',
Expires: 300
};
$.ajax({
type: "POST",
url: "/upload",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
success: function(result){
uploadToS3(result, function(status){
$('#status').text(status);
});
},
error: function(result){
console.log("ERROR",result);
}
});
});
var uploadToS3 = function(s3Url, cb){
var fd = new FormData();
var file = document.getElementById('file').files[0];
var key = 'uploads\/' + file.name;
fd.append('key', 'uploads\/' + file.name);
fd.append('acl', 'public-read');
fd.append('Content-Type', 'multipart/form-data');
fd.append('AWSAccessKeyId', 'YOUR_ACCESS_KEY');
fd.append('policy', s3Url.s3Policy);
fd.append('signature', s3Url.s3Signature);
fd.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://your-bucket.s3.amazonaws.com', true);
/////////////////////////////////////////////////////////
// Keep track of upload progress so that we can message//
// it to the user. //
/////////////////////////////////////////////////////////
var firstProgressEvent = true;
xhr.loaded = 0;
xhr.upload.addEventListener('progress', function(e) {
if (firstProgressEvent) {
firstProgressEvent = false;
}
xhr.loaded += (e.loaded - xhr.loaded);
$('progress').val((xhr.loaded / e.total) * 100);
}, false);
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 ) {
if ( xhr.status >= 200 && xhr.status < 400 ) {
cb(xhr.status);
} else {
cb(xhr.status);
}
}
};
xhr.onerror = function () {
error(xhr, xhr.status);
};
xhr.send(fd);
};
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment