javascript - 异步上传(HTTP POST)到 Amazon S3 : why aren't I getting the right callbacks?

标签 javascript ajax jquery amazon-s3

我正在尝试使用 HTTP POST 和 jQuery 异步上传文件,但我遇到了一个奇怪的问题:我无法触发正确的回调。当我上传文件时,它返回代码为 201 的“OK”状态并且我可以访问我的 S3 存储桶中的文件,但是 jQuery 每次 都会触发“错误”回调.在进一步检查 XHR 对象后,我发现:

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

在我看来,该错误似乎违反了同源策略。您可以将表单发布到另一个域,但是除了您的 JS 来自的主机之外,您不能对任何东西执行 XHR,而且我在您链接的示例中没有看到任何 XHR。

关于javascript - 异步上传(HTTP POST)到 Amazon S3 : why aren't I getting the right callbacks?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5095867/

相关文章:

javascript - Webpack Import Code Splitting 渲染 <undefined>

javascript - 未捕获的语法错误 : Unexpected token < occurring when deploying

html - 单选按钮 jQuery 更改不起作用

javascript - 更新Jquery中li的标题属性

asp.net - ASP.Net 缓存故障排除 - CacheDuration 属性似乎没有效果

javascript - Eloquent javascript 表格绘制函数 - drawRow 参数

javascript - 这是调用 javascript 函数的正确方法吗?

javascript - AJAX XMLHttpRequest POST

javascript - 来自 React 组件的 AJAX 请求

javascript - 按空格分割字符串