저는 http://pjambet.github.io/blog/direct-upload-to-s3/을 자습서로 사용하고 있습니다. 이미 CORS를 사용하도록 설정했습니다 (CORS 파일 참조). 나는 파일 업로드 쿼리의 (추가) 기능인 JSON 응답을 받는다. 실패는 서명과 정책을 얻은 후에 발생합니다. 파일을 실제로 업로드하려고하면 Amazon에서 Access Denied 오류가 발생합니다. 파일이 업로드되지 않습니다. 내가 놓친 게 있니?Amazon S3에 대한 액세스가 거부되었습니다.
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>
자바 스크립트 :
$(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)
})
},
})
})
});
펄 :
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>
그랬어! 몇 가지 정책 매개 변수를 제거해야했지만 작동했습니다! –
@RijviRajib Fail 콜백이 계속 작동하는지 확인하십시오. Iframe Transport 관련 문제점에 대해 들어 봤습니다. – Fractaliste
그래, 오류 콜백이 작동하지 않습니다 ... 유효한 업로드 응답을 받았지만 요청이 실패했습니다. 구제에 대한 아이디어가 있습니까? –