异步上传(HTTP POST)到Amazon S3:为什么我不能得到正确的回调? [英] Asynchronous uploading (HTTP POST) to Amazon S3: why aren't I getting the right callbacks?
问题描述
我试图上传使用异步HTTP POST和jQuery的文件,但我遇到一个奇怪的问题:我不能得到正确的回调火灾。当我上传文件,它返回一个OK的地位与code 201的我可以访问我的S3存储文件,但jQuery的触发错误回调的每次的时间。检查XHR对象远一点之后,我遇到了:
错误:权限被拒绝[http://192.168.2.247]获得财产Window.document从[https://pentoolcn.aplusldesign.com.s3.amazonaws.com] $ P $。 P>什么引起的?这code被采用,几乎逐字从<一个href="http://developer.amazonwebservices.com/connect/entry!default.jspa?categoryID=139&externalID=1434&fromSearchPage=true" rel="nofollow">http://developer.amazonwebservices.com/connect/entry!default.jspa?categoryID=139&externalID=1434&fromSearchPage=true和同步(正常表单提交和页面刷新),它完美地工作。
我的code是如下。
&LT; PHP // CDN服务选项Amazon S3的S3或无无[默认] $ CDN_SERVICE_TYPE =S3; $ CDN_SERVICE_TYPE =无; $ CDN_ACCESS_KEY ='[机密]'; $ CDN_SECRET_KEY ='[机密]'; $ CDN_BUCKET ='[机密]'; $ CDN_FOLDER ='[机密]'; //内斗的文件夹 $ CDN_ACL ='公共读; $ CDN_MAX_FILE_SIZE = 20 * 1048576; // MB大小限制 $ SUCCESS_REDIRECT =HTTP://。 $ _ SERVER ['SERVER_NAME']。 ($ _ SERVER ['SERVER_PORT'] =='''?':':')。 $ _ SERVER ['SERVER_PORT']。 '/'。 的index.php/ * $ _ SERVER ['SERVER_SELF'] * /。 '?好' ; // SendFileS3.php是从服务器的根目录网址 //过程从转让结果,如果查询字符串present $查询= $ _ SERVER ['QUERY_STRING']; //设置转帐单 $ expTime =时间()+(1 * 60 * 60); //现在加一小时(1小时; 60分钟; 60secs) $ expTimeStr = gmdate('Y-M-D \ TH:我:秒\ Z',$ expTime); //回声expTimeStr:。 $ expTimeStr&LT; BR /&gt;中。 //回声SUCCESS_REDIRECT:。 $ SUCCESS_REDIRECT&LT; BR /&gt;中。 //创建策略文档 $ policyDoc =' {过期:'$ expTimeStr。' 条件: {以acl:'。$ CDN_ACL'}, {斗:,$ CDN_BUCKET。'}, {success_action_status:201}, [打头-带,$键,'。$ CDN_FOLDER'], [\'开始,以\',\'$文件夹\',\'\'], [\'开始,以\',\'$文件名\',\'\'], [\'开始,以\,\上传\',\'\'], [内容长度范围,0。 $ CDN_MAX_FILE_SIZE。 '], ] } '; // //删除了success_action_redirect原因Flash不喜欢 $ policyDocFlash =' {过期:'$ expTimeStr。' 条件: {以acl:'。$ CDN_ACL'}, {斗:,$ CDN_BUCKET。'}, {success_action_status:201}, [打头-带,$键,'。$ CDN_FOLDER'], [\'开始,以\',\'$文件夹\',\'\'], [\'开始,以\',\'$文件名\',\'\'], [\'开始,以\,\上传\',\'\'], [内容长度范围,0。 $ CDN_MAX_FILE_SIZE。 '] ] } '; //回声policyDoc:。 $ policyDoc。 '&LT; BR /&GT;'; //删除政策文件CRLFs $ policyDoc =破灭(爆炸('\ r',即$ policyDoc)); $ policyDoc =破灭(爆炸('\ N',$ policyDoc)); $ policyDoc64 = base64_en code($ policyDoc); // EN code立足64 //创建策略文档签名 $ sigPolicyDoc = base64_en code(hash_hmac(SHA1,$ policyDoc64,$ CDN_SECRET_KEY,TRUE / raw_output * /)); //回声policyDoc:。 $ policyDoc。 '&LT; BR /&GT;'; //删除政策文件CRLFs $ policyDocFlash =破灭(爆炸('\ r',即$ policyDocFlash)); $ policyDocFlash =破灭(爆炸('\ N',$ policyDocFlash)); $ policyDoc64Flash = base64_en code($ policyDocFlash); // EN code立足64 //创建策略文档签名 $ sigPolicyDocFlash = base64_en code(hash_hmac(SHA1,$ policyDoc64Flash,$ CDN_SECRET_KEY,TRUE / raw_output * /)); ?&GT; &LT; HTML&GT; &LT; HEAD&GT; &LT;冠军&GT; S3 POST表格及LT; /标题&GT; &LT; META HTTP-当量=Content-Type的CONTENT =text / html的;字符集= UTF-8/&GT; &LT;链接相对=样式表的href =CSS / uploadify.css类型=文本/ CSS/&GT; &LT;脚本类型=文/ JavaScript的SRC =JS / jQuery的-1.3.2.min.js&GT;&LT; / SCRIPT&GT; &LT;脚本类型=文/ JavaScript的SRC =JS / jquery.uploadify.v2.1.4.min.js&GT;&LT; / SCRIPT&GT; &LT;脚本类型=文/ JavaScript的SRC =JS / swfobject.js&GT;&LT; / SCRIPT&GT; &LT;脚本SRC =JS / jquery.form.js类型=文/ JavaScript的字符集=utf-8&GT;&LT; / SCRIPT&GT; &LT;脚本SRC =JS / jquery.validate.min.js类型=文/ JavaScript的字符集=utf-8&GT;&LT; / SCRIPT&GT; &LT;脚本类型=文/ JavaScript的&GT; 功能的setType(){ 。的document.getElementById(内容类型)值= getMIMEtype(的document.getElementById(文件)的价值。); } VAR CDN_BUCKET =&LT; PHP的echo($ CDN_BUCKET);?&gt;中; $(文件)。就绪(函数(){ $(#远程表)。递交(函数(){ 的console.log(提交...); $(本).ajaxSubmit({ 网址:https://开头+ CDN_BUCKET +.s3.amazonaws.com /, 目标:#response, 成功:函数(响应状态,XHR){ console.info(成功!); }, 错误:函数(XHR,状态,错误){ console.error(失败); }, 完成:功能(XHR,状态){ 的console.log(完成); } }); 返回false }); }); &LT; / SCRIPT&GT; &LT; /头&GT; &LT;身体GT; &LT; DIV ID =回应的风格=边界:1px的纯黑色&GT;&LT; / DIV&GT; &LT; PHP $水库=爆炸('和;',$查询); 的foreach($水库为$ SS){ //回声'SS:。 $ SS。 '&LT; BR /&GT;'; 如果(SUBSTR($ SS,0,7)=='斗=')$ qBucket = urlde code(SUBSTR($ SS,7)); 如果(SUBSTR($ SS,0,4)=='键=')$ qKey = urlde code(SUBSTR($ SS,4)); } 如果($ qBucket!=''){ //展示成果转让 回声文件传输:。 $ qBucket。 '/'。 $ qKey。 '&LT; BR /&GT;&LT; BR /&GT;'; $ =到期时间()+ 1 * 24 * 60 * 60 / * $到期* /; $资源= $ qBucket/urlen code($ qKey)。 $ stringToSign =GET \ñ\ñ\ n $的到期\ N / $资源; //回声stringToSign:$ stringToSign&LT; BR /&GT;&LT; BR /&gt;中; $签字= urlen code(base64_en code(hash_hmac(SHA1,$ stringToSign,$ CDN_SECRET_KEY,TRUE / raw_output * /))); //回声签名:$签名&LT; BR /&GT;&LT; BR /&gt;中; $查询字符串=&LT;一href='http://s3.amazonaws.com/$resource?AWSAccessKeyId=$CDN_ACCESS_KEY&Expires=$expires&Signature=$signature'>$bucket/$key</a>"; 回声URL(专用读取):$ QUERYSTRING&LT; BR /&GT;&LT; BR /&gt;中; 回声URL(公共读):http://s3.amazonaws.com/。 $ qBucket。 '/'。 $ qKey。 '&LT; BR /&GT;&LT; BR /&GT;'; } ?&GT; &LT;形式ID =遥控型的方法=邮报行动=? ENCTYPE =的multipart / form-data的&GT; &LT;! - 亚马逊的配置 - &GT; &LT;输入类型=隐藏名称=键值=&LT; PHP的echo($ CDN_FOLDER'$ {文件名});?&gt;中/&GT; &LT;输入类型=隐藏名称=AWSAccessKeyId值=&LT; PHP的echo($ CDN_ACCESS_KEY);?&gt;中/&GT; &LT;输入类型=隐藏名称=控制列表,acl值=&LT; PHP的echo($ CDN_ACL);?&gt;中/&GT; &LT;输入类型=隐藏名称=success_action_status值=201/&GT; &LT;输入类型=隐藏名称=政策值=&LT; PHP的echo($ policyDoc64);?&gt;中/&GT; &LT;输入类型=隐藏名称=签名值=&LT; PHP的echo($ sigPolicyDoc);?&gt;中/&GT; &LT;输入类型=隐藏名称=文件夹值=/&GT; &LT;输入类型=隐藏名称=文件名值=/&GT; &LT;! - 文件数据 - &GT; 文件上传到S3: &LT;输入名称=文件ID =file_upload类型=文件&GT; &LT; BR /&GT;&LT; BR /&GT; &LT;输入类型=提交值=上传文件到S3&GT; &LT; /形式GT; &LT; /身体GT; &LT; / HTML&GT;
解决方案检查XHR对象后
这是错误看起来像一个相同来源,违反政策给我。你可以做一个表单提交到另一个域名,但你不能做一个XHR以外的任何其他的JS来自主机,我没有看到你链接样品任何XHR。
I'm attempting to upload a file asynchronously using HTTP POST and jQuery, but I'm running into a strange issue: I can't get the right callback to fire. When I upload a file, it returns an "OK" status with code 201 and I can access file on my S3 bucket, but jQuery fires the "error" callback every time. After inspecting the XHR object a little 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 causing 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 submit 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('Y-m-d\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>
解决方案After inspecting the XHR object
That error looks like a same-origin-policy violation to me. You can do a form post to another domain, but you can't do an XHR to anything other than the host your JS came from, and I don't see any XHR on the sample you linked.
这篇关于异步上传(HTTP POST)到Amazon S3:为什么我不能得到正确的回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!