2015-08-24 54 views
3

我試圖使用PUT請求將文件上傳到Amazon S3。我使用boto生成我簽名的網址。如果我這樣做使用簽名URL上傳到Amazon S3適用於curl,但不適用於javascript

curl --upload-file test.jpg $SIGNED_URL 

然後上傳工作正常(所以沒有簽署的URL的問題)。我也用捲曲的方式將引用者設置爲各種各樣的東西,並且它仍然有效,所以我不認爲還有CORS問題。我試圖用JavaScript上傳一個文件blob,如下所示:

var xmlhttp = new XMLHttpRequest();  
xmlhttp.open("PUT", $SIGNED_URL); 
xmlhttp.setRequestHeader('Content-Type', blob.type); 
xmlhttp.send(blob); 

這總是返回403 Forbidden錯誤。我發現很難在網上找到任何有關從javascript向S3發佈PUTing數據的信息。我現在意識到POST表單數據更常見,但是有什麼方法可以修改我正在做的工作嗎?

編輯:我已經找到了錯誤的身體現在:

> <Error><Code>SignatureDoesNotMatch</Code> <Message>The request 
> signature we calculated does not match the signature you provided. 
> Check your key and signing method.</Message> 

這樣看來,簽約是問題。同樣,當我用curl使用它時(甚至在javascript失敗後),同樣的確切網址也能正常工作。

回答

5

問題是curl沒有發送的'Content-Header'。無論您是否明確添加,Chrome都會發送此標頭。要獲得一個可以使用這個頭文件的簽名url,你需要在boto中傳遞headers = {'Content-Type':type}給generate_url。

+0

感謝張貼這個。 – Feargal

+0

這個答案拯救了我幾個小時的生命:) – Rubico

0

對我來說,問題是我沒有設置內容類型,同時產生presigned URL,所以補充說,雖然產生presigned網址

java.util.Date expiration = new java.util.Date(); 
     long msec = expiration.getTime(); 
     msec += 60 * 60 * 1000; // 1 hour. 
     expiration.setTime(msec); 

     GeneratePresignedUrlRequest generatePresignedUrlRequest = 
       new GeneratePresignedUrlRequest("bucket_name", "someRandomKey"); 
     generatePresignedUrlRequest.setMethod(HttpMethod.PUT); // Default. 
     generatePresignedUrlRequest.setExpiration(expiration); 
     generatePresignedUrlRequest.setContentType("application/octet-stream"); 

     URL s = s3Client.generatePresignedUrl(generatePresignedUrlRequest); 
     System.out.println("Secure PUT URL is "+s); 

這裏是捲曲

curl -v -X PUT \ 
    'generated_secure_url' \ 
    -H 'Content-Type:application/octet-stream' \ 
    --data-binary '@swiggy-hackathon.jpg' 
相關問題