稍微修改过的URL版本:
https://s3.amazonaws.com/somebucket/pre-signed-url-key-2?AWSAccessKeyId=BKIAIQ6H5Z7BG6KZ2ZUA\u0026amp;Expires=1425617244\u0026amp;Signature=GWcRM5ZIrAKnMJBsxyfm/9fyuBk=
我知道它是一个有效的预签名网址,因为我可以使用curl上传文件
curl -v –upload-file somefile.txt“https://s3.amazonaws.com/somebucket/pre-signed-url-key-2?AWSAccessKeyId=BKIAIQ6H5Z7BG6KZ2ZUA\u0026amp;Expires=1425617244\u0026amp;Signature=GWcRM5ZIrAKnMJBsxyfm/9fyuBk=”
当我尝试使用以下Javascript将文件上传到同一URL时:
function ajaxUsingPresignedUrlPut() { $.ajax({ url: presignedURLPUT,type: 'PUT',data: 'blah blah blah',success: function () { console.log('Uploaded data successfully.'); } }).done(function (data) { console.log("DONE : " + data); }).fail(function (e,r) { console.log("FAIL"); }); }
我得到403状态和responseText
<?xml version="1.0" encoding="UTF-8"?> <Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>BKIAIQ6H5Z7BG6KZ2ZUA</AWSAccessKeyId><StringToSign>PUT application/x-www-form-urlencoded; charset=UTF-8 1425617244 /somebucket/pre-signed-url-key-2</StringToSign><SignatureProvided>GWcRM5ZIrAKnMJAsxyfm/9fyuAk=</SignatureProvided><StringToSignBytes>50 55 54 0a 0a 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 3b 20 63 68 61 72 73 65 74 3d 55 54 46 2d 38 0a 31 34 32 35 36 31 37 32 34 34 0a 2f 6e 6b 6f 6e 64 72 61 74 5f 62 75 63 6b 65 74 2f 70 72 65 2d 73 69 67 6e 65 64 2d 75 72 6c 2d 6b 65 79 2d 32</StringToSignBytes><RequestId>3C8298CAC404C6F5</RequestId><HostId>uCkzA//CdCLi4SINifkIe0WH6GOlCJBgFlN8ghx8NnULEe+QVslsdoUsJc4AUdA8</HostId></Error>
我在S3存储桶上配置了以下CORS策略:
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>HEAD</AllowedMethod> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <ExposeHeader>ETag</ExposeHeader> <ExposeHeader>Content-Length</ExposeHeader> <ExposeHeader>Content-Type</ExposeHeader> <ExposeHeader>Connection</ExposeHeader> <ExposeHeader>Date</ExposeHeader> <ExposeHeader>Server</ExposeHeader> <ExposeHeader>x-amz-delete-marker</ExposeHeader> <ExposeHeader>x-amz-id-2</ExposeHeader> <ExposeHeader>x-amz-request-id</ExposeHeader> <ExposeHeader>x-amz-version-id</ExposeHeader> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration>
相同的JavaScript代码适用于预先签名的GET URL:
https://s3.amazonaws.com/somebucket/pre-signed-url-key-2?AWSAccessKeyId=BKIBIQ6H5Z7LG6KZ2ZUB\u0026amp;Expires=1425616588\u0026amp;Signature=qMPpuzMwxonYPDQETdLafEQGqMU=
function ajaxUsingPresignedUrlGET() { $.ajax({ url: presignedURLGET,type: 'GET',r) { console.log("FAIL"); }); }
我现在唯一猜到的是URL是PUT url包含/并且查看http://www.w3schools.com/tags/ref_urlencode.asp代表/可能导致浏览器出现问题?或者也许我完全离开这里,还有一些我遗漏的问题.
public S3GeneratePresignedUrlDemo(HttpMethod httpMethod) { this.httpMethod = httpMethod; System.out.println("HTTP METHOD : " + this.httpMethod); } @Override public void goImpl() throws Exception { GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName,KEY); request.setMethod(httpMethod); request.setExpiration(createDateNHoursFromNow(24)); URL url = s3Client.generatePresignedUrl(request); System.out.println(url); } private static Date createDateNHoursFromNow(int hours){ Date date = new Date(); long millis = date.getTime(); final int millisInSecond = 1000; final int secondsInMinute = 60; final int minutesInHour = 60; millis += millisInSecond * secondsInMinute * minutesInHour * hours; date.setTime(millis); return date; }`
解决方法
headers: {'Content-Type': 'text/plain;charset=UTF-8'},
到AJAX
function ajaxUsingPresignedUrlPut() { $.ajax({ url: presignedURLPUT,headers: {'Content-Type': 'text/plain;charset=UTF-8'},success: function () { console.log('Uploaded data successfully.'); } }).done(function (data) { console.log("DONE : " + data); }).fail(function (arg1,arg2) { console.log("FAIL"); }); }
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName,KEY); request.setContentType("text/plain;charset=UTF-8"); //...