Last active
December 23, 2015 15:49
-
-
Save bathtimefish/6657812 to your computer and use it in GitHub Desktop.
Direct Browser Uploading to Amazon S3 cf. http://goo.gl/PAB5Ou
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//wrote for AMD | |
define([], function () { | |
function createCORSRequest(method, url) | |
{ | |
var xhr = new XMLHttpRequest(); | |
if ("withCredentials" in xhr) { | |
xhr.open(method, url, true); | |
} else if (typeof XDomainRequest != "undefined") { | |
xhr = new XDomainRequest(); | |
xhr.open(method, url); | |
} else { | |
xhr = null; | |
} | |
return xhr; | |
} | |
function handleFileSelect(evt) | |
{ | |
setProgress(0, 'Upload started.'); | |
var files = evt.target.files; | |
var output = []; | |
for (var i = 0, f; f = files[i]; i++) { | |
uploadFile(f); | |
} | |
} | |
/** | |
* Execute the given callback with the signed response. | |
*/ | |
function executeOnSignedUrl(file, callback) | |
{ | |
var xhr = new XMLHttpRequest(); | |
var url = 's3url.php?name=' + file.name + '&type=' + file.type; | |
xhr.open('GET', url, true); | |
// Hack to pass bytes through unprocessed. | |
xhr.overrideMimeType('text/plain; charset=x-user-defined'); | |
xhr.onreadystatechange = function(e) { | |
if (this.readyState == 4 && this.status == 200) { | |
callback(decodeURIComponent(this.responseText)); | |
} else if(this.readyState == 4 && this.status != 200) { | |
setProgress(0, 'Could not contact signing script. Status = ' + this.status); | |
} | |
}; | |
xhr.send(); | |
} | |
function uploadFile(file) | |
{ | |
executeOnSignedUrl(file, function(signedURL) { | |
uploadToS3(file, signedURL); | |
}); | |
} | |
/** | |
* Use a CORS call to upload the given file to S3. Assumes the url | |
* parameter has been signed and is accessable for upload. | |
*/ | |
function uploadToS3(file, url) | |
{ | |
var xhr = createCORSRequest('PUT', url); | |
if (!xhr) { | |
setProgress(0, 'CORS not supported'); | |
} | |
else { | |
xhr.onload = function() { | |
if(xhr.status == 200) { | |
setProgress(100, 'Upload completed.'); | |
} else { | |
setProgress(0, 'Upload error: ' + xhr.status); | |
} | |
}; | |
xhr.onerror = function(e) { | |
setProgress(0, 'XHR error.'); | |
}; | |
xhr.upload.onprogress = function(e) { | |
if (e.lengthComputable) | |
{ | |
var percentLoaded = Math.round((e.loaded / e.total) * 100); | |
setProgress(percentLoaded, percentLoaded == 100 ? 'Finalizing.' : 'Uploading.'); | |
} | |
}; | |
xhr.setRequestHeader('Content-Type', file.type); | |
xhr.setRequestHeader('x-amz-acl', 'public-read'); | |
xhr.send(file); | |
} | |
} | |
function setProgress(percent, statusLabel) | |
{ | |
//console.log("setProgress=" + percent); | |
var progress = document.querySelector('.percent'); | |
progress.style.width = percent + '%'; | |
progress.textContent = percent + '%'; | |
document.getElementById('progress_bar').className = 'loading'; | |
document.getElementById('status').innerText = statusLabel; | |
} | |
window.onload = function() { | |
document.getElementById('files').addEventListener('change', handleFileSelect, false); | |
setProgress(0, 'Waiting for upload.'); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html><!-- Yeoman generator-webapp --> | |
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> | |
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> | |
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> | |
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<title>AWS S3 Direct Upload Tests</title> | |
<meta name="description" content=""> | |
<meta name="viewport" content="width=device-width"> | |
<!-- Place favicon.ico and apple-touch-icon.png in the root directory --> | |
<!-- build:css(.tmp) styles/main.css --> | |
<link rel="stylesheet" href="styles/main.css"> | |
<!-- endbuild --> | |
</head> | |
<body> | |
<!--[if lt IE 10]> | |
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> | |
<![endif]--> | |
<div class="container"> | |
<div class="header"> | |
<ul class="nav nav-pills pull-right"> | |
<li class="active"><a href="#">Home</a></li> | |
<li><a href="#">About</a></li> | |
<li><a href="#">Contact</a></li> | |
</ul> | |
<h3 class="text-muted">AWS S3 Direct Upload Test</h3> | |
</div> | |
<div > | |
<div> | |
<h3>File selection:</h3> | |
<input type="file" id="files" name="files[]" multiple /> | |
</div> | |
<div> | |
<h3>Progress:</h3> | |
<div id="progress_bar"><div class="percent">0%</div></div> | |
<div><span id="status"></span></div> | |
</div> | |
</div> | |
<div class="footer"> | |
<p>♥ from the Yeoman team</p> | |
</div> | |
</div> | |
<!-- build:js scripts/vendor.js --> | |
<!-- bower:js --> | |
<script src="bower_components/jquery/jquery.js"></script> | |
<!-- endbower --> | |
<!-- endbuild --> | |
<!-- build:js scripts/main.js --> | |
<script data-main="scripts/main" src="bower_components/requirejs/require.js"></script> | |
<!-- endbuild --> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#progress_bar { | |
width: 200px; | |
margin: 10px 0; | |
padding: 3px; | |
border: 1px solid #000; | |
font-size: 14px; | |
clear: both; | |
opacity: 0; | |
-moz-transition: opacity 1s linear; | |
-o-transition: opacity 1s linear; | |
-webkit-transition: opacity 1s linear; | |
} | |
#progress_bar.loading { | |
opacity: 1.0; | |
} | |
#progress_bar .percent { | |
background-color: #99ccff; | |
height: auto; | |
width: 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> | |
<CORSRule> | |
<AllowedOrigin>http://www.example.com</AllowedOrigin> | |
<AllowedMethod>PUT</AllowedMethod> | |
<AllowedHeader>Content-Type</AllowedHeader> | |
<AllowedHeader>x-amz-acl</AllowedHeader> | |
<AllowedHeader>origin</AllowedHeader> | |
</CORSRule> | |
<CORSRule> | |
<AllowedOrigin>*</AllowedOrigin> | |
<AllowedMethod>GET</AllowedMethod> | |
</CORSRule> | |
</CORSConfiguration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// | |
// Change the following settings | |
// | |
$S3_KEY='S3 Key Here'; | |
$S3_SECRET='S3 Secret Here'; | |
$S3_BUCKET='/uploadtestbucket'; | |
$EXPIRE_TIME=(60 * 5); // 5 minutes | |
$S3_URL='http://s3.amazonaws.com'; | |
$objectName='/' . $_GET['name']; | |
$mimeType=$_GET['type']; | |
$expires = time() + $EXPIRE_TIME; | |
$amzHeaders= "x-amz-acl:public-read"; | |
$stringToSign = "PUT\n\n$mimeType\n$expires\n$amzHeaders\n$S3_BUCKET$objectName"; | |
$sig = urlencode(base64_encode(hash_hmac('sha1', $stringToSign, $S3_SECRET, true))); | |
$url = urlencode("$S3_URL$S3_BUCKET$objectName?AWSAccessKeyId=$S3_KEY&Expires=$expires&Signature=$sig"); | |
echo $url; | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment