1

我有一個在AWS S3上託管的靜態網站。該網站可以訪問或者: https://s3.amazonaws.com/example-bucket-name-to-avoid-spam/index.html 或者 http://example-bucket-name-to-avoid-spam.s3-website-us-east-1.amazonaws.com/如何配置S3存儲桶以允許發佈到API網關而沒有405錯誤

當用戶完成表單和頁面上的驗證碼,並按下提交以下JavaScript被觸發:

<script> 
 
    // Replace the YOUR_API_ENDPOINT_URL with yours 
 
    // It should look something like this: 
 
    // https://qw324asdasd.execute-api.us-east-1.amazonaws.com/dev/api/sendSms 
 
    const API_ENDPOINT = 'https://fak3ur1.execute-api.us-east-1.amazonaws.com/dev/api/sendSms'; 
 
    var messageDiv = document.getElementById('error-message') 
 
    // Handle public api call 
 
    document.getElementById('send-text').addEventListener('click', function() { 
 
     const captchtaResponse = grecaptcha.getResponse() || false 
 
     const textMessage = document.getElementById('message').value 
 
     const phoneNumber = document.getElementById('phone-number').value 
 

 
     if (!textMessage) { 
 
     messageDiv.innerHTML = 'Remember to enter a message!' 
 
     return false 
 
     } 
 

 
     if (!phoneNumber) { 
 
     messageDiv.innerHTML = 'Don\'t forget to enter a phone number!' 
 
     return false 
 
     } 
 

 
     if (!captchtaResponse) { 
 
     messageDiv.innerHTML = 'Complete the Captcha please!' 
 
     return false 
 
     } 
 

 
     const data = JSON.stringify({ 
 
     to: phoneNumber, 
 
     message: textMessage, 
 
     captcha: captchtaResponse 
 
     }) 
 

 
     // post to API with native browser Fetch 
 
     const getdata = fetch(API_ENDPOINT, { 
 
     headers: { 
 
      "Content-type": "application/json" 
 
     }, 
 
     method: 'POST', 
 
     body: data, 
 
     mode: 'cors', 
 
     cache: false, 
 
     }); 
 

 
     getdata.then(function(response) { 
 
     response.json().then(function(data) { 
 
      console.log('Response:', data); 
 
      const body = JSON.parse(data.body); 
 
      messageDiv.textContent = ''; 
 
      messageDiv.textContent = (body && body.message) ? body.message : ''; 
 
     }); 
 
     }).catch(function(err) { 
 
     console.log(err) 
 
     }); 
 
    }); 
 
    </script>

這成功地將POST發送到AWS API網關,該網關正確處理請求並將Twilio文本發送到所需的電話麻木呃。

我也證實了這郵差API網關/λ響應本身是否正確回來:

{ 
    "statusCode": 200, 
    "headers": { 
     "Access-Control-Allow-Origin": "*" 
    }, 
    "body": "{\"message\":\"Text message successfully sent!\",\"data\":{\"dateCreated\":\"2017-07-06T16:49:00.000Z\",\"dateUpdated\":\"2017-07-06T16:49:00.000Z\",\"from\":\"+13334445566\",\"body\":\"Sent from your Twilio trial account - test 5 with postman - looking at Lambda logs\"}}" 
} 

問題發生後POST是(大概)發送到API網關。靜態網站重定向到一個錯誤頁面,這個消息在非HTTPS URL以上時:

405 Method Not Allowed 

Code: MethodNotAllowed 
Message: The specified method is not allowed against this resource. 
Method: POST 
ResourceType: OBJECT 
RequestId: IDSTRING123 
HostId: Longhostidthing1237ygausdhasdgylh231ctidasd= 

這對於HTTPS URL:

<Error> 
<Code>MethodNotAllowed</Code> 
<Message> 
The specified method is not allowed against this resource. 
</Message> 
<Method>POST</Method> 
<ResourceType>OBJECT</ResourceType> 
<RequestId>IDSTRING123</RequestId> 
<HostId> 
Longhostidthing1237ygausdhasdgylh231ctidasd= 
</HostId> 
</Error> 

起初,我認爲這是一個CORS問題,但我檢查和複查幾次在桶中的CORS政策是非常寬鬆:

<?xml version="1.0" encoding="UTF-8"?> 
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 
<CORSRule> 
    <AllowedOrigin>*</AllowedOrigin> 
    <AllowedMethod>PUT</AllowedMethod> 
    <AllowedMethod>POST</AllowedMethod> 
    <AllowedMethod>DELETE</AllowedMethod> 
    <MaxAgeSeconds>0</MaxAgeSeconds> 
    <AllowedHeader>*</AllowedHeader> 
</CORSRule> 
<CORSRule> 
    <AllowedOrigin>*</AllowedOrigin> 
    <AllowedMethod>GET</AllowedMethod> 
    <MaxAgeSeconds>0</MaxAgeSeconds> 
    <AllowedHeader>*</AllowedHeader> 
</CORSRule> 
</CORSConfiguration> 

我也與周圍的這幾次撥弄確認我被作爲一個寬容可能。

最後,我在Chrome中嘗試了這種隱身模式,在一個單獨的配置文件中清除了Cookie和所有瀏覽數據,以及上述所有使用從瀏覽器端禁用CORS的插件。這些嘗試都不能解決我的問題。

任何想法?

+2

我覺得你太過複雜了。這聽起來像是你正在通過JavaScript發佈一些東西到API網關,但是也發佈了同樣的東西給S3?我的猜測是你需要簡單地阻止默認表單發佈操作,因爲你正在通過javascript處理它。 –

+0

@MarkB你說得對!防止默認或移除帖子操作解決了這個問題。 – Fernando

+0

@MarkB如果你發佈了一個答案,我會接受它。 – Fernando

回答

1

馬克B是正確的。

「這聽起來像你正在通過JavaScript發佈一些東西到API網關,但隨後也發佈了相同的東西到S3?我的猜測是你需要簡單地防止默認的表單發佈操作發生,因爲你正在通過JavaScript處理它「。

編輯: 這個最簡單的解決方法是改變這一行:

document.getElementById('send-text').addEventListener('click', function() { 

這樣:

document.getElementById('send-text').addEventListener('click', function (event) { 

而且在隨後的行調用event.preventDefault()防止默認代碼運行和發佈帖子請求。

+1

爲了未來訪問者的利益,請編輯此答案以準確顯示如何修復表單以使其符合要求。 –

+1

@ Michael-sqlbot更新。 – Fernando

相關問題