I have a static website hosted on AWS S3. The website can be accessed from either: https://s3.amazonaws.com/example-bucket-name-to-avoid-spam/index.html Or http://example-bucket-name-to-avoid-spam.s3-website-us-east-1.amazonaws.com/
When a user completes the form and the captcha on the page and presses submit the following JavaScript is triggered:
<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>
This successfully sends a POST through to the AWS API Gateway which processes the request correctly and sends a text with Twilio to the desired phone number.
I've also confirmed in Postman that the API Gateway/Lambda response itself is correctly coming back:
{
"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\"}}"
}
The issue happens after that POST is (presumably) sent to API Gateway. The static site redirects to an error page with this message when on the non-https url above:
405 Method Not Allowed
Code: MethodNotAllowed
Message: The specified method is not allowed against this resource.
Method: POST
ResourceType: OBJECT
RequestId: IDSTRING123
HostId: Longhostidthing1237ygausdhasdgylh231ctidasd=
And this for the 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>
Initially I thought this was a CORS issue, but I've checked and rechecked several times the CORS policy on the bucket is very permissive:
<?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>
I've also fiddled around with this a few times to confirm I was being as permissive as possible.
Finally, I've tried this incognito in Chrome, with cookies and all browsing data cleared in a separate profile, and all of the above with a plugin that disables CORS from the browser-side. None of these attempts appear to resolve my issue.
Any ideas?