Asynchronous download (HTTP POST) on Amazon S3: why am I not getting the right callbacks?

I am trying to upload a file asynchronously using HTTP POST and jQuery, but I am having a strange problem: I cannot get the correct callback to start. When I upload a file, it returns an OK status with code 201 , and I can access the file in my S3 statement , but jQuery fails every time. After inspecting the XHR object a bit further, I came across:

  Error: Permission denied for [http://192.168.2.247] to get property Window.document from [https://pentoolcn.aplusldesign.com.s3.amazonaws.com]. 

What could be the reason for this? This code is taken almost verbatim from http://developer.amazonwebservices.com/connect/entry!default.jspa?categoryID=139&externalID=1434&fromSearchPage=true and synchronously (normal form submission and page refresh), it worked perfectly.

My code is below.

<?php // CDN service options are Amazon S3 "S3" or None "none" [default] $CDN_SERVICE_TYPE = "S3"; $CDN_SERVICE_TYPE = 'none'; $CDN_ACCESS_KEY = '[CONFIDENTIAL]'; $CDN_SECRET_KEY = '[CONFIDENTIAL]'; $CDN_BUCKET = '[CONFIDENTIAL]'; $CDN_FOLDER = '[CONFIDENTIAL]'; // folder within bucket $CDN_ACL = 'public-read'; $CDN_MAX_FILE_SIZE = 20 * 1048576; // MB size limit $SUCCESS_REDIRECT = 'http://' . $_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT']=='' ? '' : ':') . $_SERVER['SERVER_PORT'] . '/' . 'index.php'/*$_SERVER['SERVER_SELF']*/ . '?ok' ; // SendFileS3.php is URL from server root // process result from transfer, if query string present $query = $_SERVER['QUERY_STRING']; // setup transfer form $expTime = time() + (1 * 60 * 60); // now plus one hour (1 hour; 60 mins; 60secs) $expTimeStr = gmdate('Ymd\TH:i:s\Z', $expTime); //echo 'expTimeStr: '. $expTimeStr ."<BR/>"; //echo 'SUCCESS_REDIRECT: '. $SUCCESS_REDIRECT ."<BR/>"; // create policy document $policyDoc = ' {"expiration": "' . $expTimeStr . '", "conditions": [ {"acl": "' . $CDN_ACL . '"}, {"bucket": "' . $CDN_BUCKET . '"}, {"success_action_status": "201"}, ["starts-with", "$key", "' . $CDN_FOLDER . '"], [\'starts-with\', \'$folder\',\'\'], [\'starts-with\', \'$filename\', \'\'], [\'starts-with\',\'Upload\', \'\'], ["content-length-range", 0, ' . $CDN_MAX_FILE_SIZE . '], ] } '; // // Removed the success_action_redirect cause Flash doesn't like it $policyDocFlash = ' {"expiration": "' . $expTimeStr . '", "conditions": [ {"acl": "' . $CDN_ACL . '"}, {"bucket": "' . $CDN_BUCKET . '"}, {"success_action_status": "201"}, ["starts-with", "$key", "' . $CDN_FOLDER . '"], [\'starts-with\', \'$folder\',\'\'], [\'starts-with\', \'$filename\', \'\'], [\'starts-with\',\'Upload\', \'\'], ["content-length-range", 0, ' . $CDN_MAX_FILE_SIZE . '] ] } '; //echo "policyDoc: " . $policyDoc . '<BR/>'; // remove CRLFs from policy document $policyDoc = implode(explode('\r', $policyDoc)); $policyDoc = implode(explode('\n', $policyDoc)); $policyDoc64 = base64_encode($policyDoc); // encode to base 64 // create policy document signature $sigPolicyDoc = base64_encode(hash_hmac("sha1", $policyDoc64, $CDN_SECRET_KEY, TRUE/*raw_output*/)); //echo "policyDoc: " . $policyDoc . '<BR/>'; // remove CRLFs from policy document $policyDocFlash = implode(explode('\r', $policyDocFlash)); $policyDocFlash = implode(explode('\n', $policyDocFlash)); $policyDoc64Flash = base64_encode($policyDocFlash); // encode to base 64 // create policy document signature $sigPolicyDocFlash = base64_encode(hash_hmac("sha1", $policyDoc64Flash, $CDN_SECRET_KEY, TRUE/*raw_output*/)); ?> <html> <head> <title>S3 POST Form</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="css/uploadify.css" type="text/css" /> <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script> <script type="text/javascript" src="js/jquery.uploadify.v2.1.4.min.js"></script> <script type="text/javascript" src="js/swfobject.js"></script> <script src="js/jquery.form.js" type="text/javascript" charset="utf-8"></script> <script src="js/jquery.validate.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> function setType(){ document.getElementById("Content-Type").value = getMIMEtype(document.getElementById("file").value); } var CDN_BUCKET = "<?php echo($CDN_BUCKET); ?>"; $(document).ready(function() { $("#remote-form").submit(function() { console.log("Submitting..."); $(this).ajaxSubmit({ url: "https://"+CDN_BUCKET+".s3.amazonaws.com/", target: '#response', success: function(response, status, xhr) { console.info("Success!"); }, error: function(xhr, status, error) { console.error("Failure."); }, completed: function(xhr, status) { console.log("Done."); } }); return false }); }); </script> </head> <body> <div id="response" style="border: 1px solid black"></div> <?php $res = explode('&', $query); foreach($res as $ss) { //echo 'ss: ' . $ss . '<BR/>'; if(substr($ss,0,7) == 'bucket=') $qBucket = urldecode(substr($ss,7)); if(substr($ss,0,4) == 'key=') $qKey = urldecode(substr($ss,4)); } if($qBucket != '') { // show transfer results echo 'File transferred: ' . $qBucket . '/' . $qKey . '<BR/><BR/>'; $expires = time() + 1*24*60*60/*$expires*/; $resource = $qBucket."/".urlencode($qKey); $stringToSign = "GET\n\n\n$expires\n/$resource"; //echo "stringToSign: $stringToSign<BR/><BR/>"; $signature = urlencode(base64_encode(hash_hmac("sha1", $stringToSign, $CDN_SECRET_KEY, TRUE/*raw_output*/))); //echo "signature: $signature<BR/><BR/>"; $queryString = "<a href='http://s3.amazonaws.com/$resource?AWSAccessKeyId=$CDN_ACCESS_KEY&Expires=$expires&Signature=$signature'>$bucket/$key</a>"; echo "URL (private read): $queryString<BR/><BR/>"; echo 'URL (public read) : http://s3.amazonaws.com/' . $qBucket . '/' . $qKey . '<BR/><BR/>'; } ?> <form id="remote-form" method="post" action="?" enctype="multipart/form-data"> <!-- amazon configuration --> <input type="hidden" name="key" value="<?php echo($CDN_FOLDER.'${filename}'); ?>" /> <input type="hidden" name="AWSAccessKeyId" value="<?php echo($CDN_ACCESS_KEY); ?>" /> <input type="hidden" name="acl" value="<?php echo($CDN_ACL); ?>" /> <input type="hidden" name="success_action_status" value="201" /> <input type="hidden" name="policy" value="<?php echo($policyDoc64); ?>" /> <input type="hidden" name="signature" value="<?php echo($sigPolicyDoc); ?>" /> <input type="hidden" name="folder" value="" /> <input type="hidden" name="Filename" value="" /> <!-- file data --> File to upload to S3: <input name="file" id="file_upload" type="file"> <br/><br/> <input type="submit" value="Upload File to S3"> </form> </body> </html> 
+4
source share
3 answers

After checking the XHR object

This error looks like a violation with the same source code for me. You can send the form message to another domain, but you cannot do XHR for anything other than the host from which your JS came from, and I do not see XHR on the sample that you linked.

+2
source

I would recommend creating an invisible iframe and passing you the form. So breaking XHR with the same source code will not be a problem.

+2
source

Now it can be installed using CORS. Check out http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

0
source

Source: https://habr.com/ru/post/1341026/


All Articles