我正在使用http://pjambet.github.io/blog/direct-upload-to-s3/作为教程。我已经启用了CORS(参见CORS文件)。我得到了JSON响应,这是文件上传查询的好(在添加中)功能。获得签名和策略后发生故障。在尝试实际上传文件时,我从Amazon获得了Access Denied错误。该文件无法上传。我错过了什么吗?
HTML:
<form class="file_upload" action="https://<% $AWSBUCKET %>.s3.amazonaws.com" method="post" enctype="multipart/form-data">
<input type="hidden" name="key" />
<input type="hidden" name="policy" />
<input type="hidden" name="signature" />
<input type="hidden" name="AWSAccessKeyId" value="<% $AWSACCESS %>" />
<input type="hidden" name="acl" value="public-read" />
<input type="hidden" name="success_action_status" value="201" />
<div class="fileupload-content">
<div class="fileupload-progress">
</div>
</div>
<div class="file-upload">
<span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Select files...</span>
<input type="file" name="file" multiple>
</span>
<div class="progress progress-striped active">
<div class="bar">
</div>
</div>
使用Javascript:
$(function() {
$('.file_upload').each(function() {
var form = $(this)
$(this).fileupload({
url: form.attr('action'),
type: 'POST',
autoUpload: true,
dataType: 'xml', // This is really important as s3 gives us back the url of the file in a XML document
add: function (event, data) {
$.ajax({
url: "s3signed.html",
type: 'GET',
dataType: 'json',
data: {filename: data.files[0].name, max_file_size : <% $MAX_FILE_SIZE %>}, // send the file name to the server so it can generate the key param
async: false,
success: function(data) {
// Now that we have our data, we update the form so it contains all
// the needed data to sign the request
form.find('input[name=key]').val(data.key)
form.find('input[name=policy]').val(data.policy)
form.find('input[name=signature]').val(data.signature)
console.log(data.key);
console.log(data.policy);
console.log(data.signature);
}
})
data.submit();
},
send: function(e, data) {
$('.progress').fadeIn();
},
progress: function(e, data){
// This is what makes everything really cool, thanks to that callback
// you can now update the progress bar based on the upload progress
var percent = Math.round((e.loaded / e.total) * 100)
$('.bar').css('width', percent + '%')
},
fail: function(e, data) {
console.log('fail');
console.log(data);
console.log(e);
},
success: function(data) {
// Here we get the file url on s3 in an xml doc
var url = $(data).find('Location').text()
$('#real_file_url').val(url) // Update the real input in the other form
},
done: function (event, data) {
$('.progress').fadeOut(300, function() {
$('.bar').css('width', 0)
})
},
})
})
});
的Perl:
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex);
use MIME::Base64;
use Data::Uniqid qw ( uniqid );
my $uniqid = uniqid;
my $key = "upload/$uniqid/$filename";
my $policy = s3PolicyDocument($AWSBUCKET, $max_file_size, $key);
my $signature = s3Signature($AWSSECRET, $policy);
my %response = (
policy => $policy,
signature => $signature,
key => $key,
success_action_status => 201
);
use JSON;
print JSON::encode_json(\%response);
sub s3PolicyDocument {
my ($AWSBUCKET, $max_file_size, $key) = @_;
use DateTime;
my $dt = DateTime->now;
$dt->add(minutes => 30);
my $policy = '{"expiration": "'.$dt.'",
"conditions": [
{"bucket": "'.$AWSBUCKET.'"},
{"acl": "public-read"},
["starts-with", "$key", ""],
["starts-with", "$Content-Type", ""],
["starts-with", "$name", ""],
["starts-with", "$Filename", ""],
["content-length-range", 0, '.$max_file_size.'],
{"success_action_status": "201"},
]
}';
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex);
use MIME::Base64;
$policy = encode_base64($policy);
$policy =~ s/\n//g;
return $policy;
}
sub s3Signature {
my($AWSSECRET, $policy) = @_;
my $signature = encode_base64(hmac_sha1($policy, $AWSSECRET));
$signature =~ s/\n//g;
return $signature;
}
CORS:
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
亚马逊回应:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>2448EA4E8E1F5377</RequestId>
<HostId>NlbqOAnjhPnqQLpaJRY1cVC6nFJ3ziVK+7ENrgILhA2njekXnp4mowv7jyTE2Z7K</HostId>
</Error>
答案 0 :(得分:2)
根据跨网站上传文档,您应该使用forceIframeTransport选项。
$(this).fileupload({
forceIframeTransport : true,
...
});
答案 1 :(得分:1)
请按照以下步骤操作 转到s3 您尝试访问的文件(公开可访问) 只需右击 - &gt;公开
这可以解决您的问题。