I've been struggling so long with the error below. I've tried so many tutorials and stackoverflow answers and none of the solutions fixes my problem.
Access to XMLHttpRequest at 'https://xxx' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I'm using SAM serverless to create my api.
template.yaml:
Globals:
Function:
Timeout: 10
Api:
Cors:
AllowMethods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
AllowOrigin: "'*'"
My lambda function: Both my GET response and OPTIONS response has the following headers that is returned:
headers: {
"Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
"Access-Control-Allow-Origin": "'*'",
"Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
}
My API get in my ReactJs application using amplify:
API.get(apiName, path, {
headers: {
"Access-Control-Allow-Origin": "*",
// "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with",
// "Access-Control-Allow-Methods": "OPTIONS,POST,GET,PUT,DELETE",
// 'Content-Type': 'application/json'
}
})
I have tried every combination of Access-Control-Allow-Headers, Access-Control-Allow-Methods in my template.yaml, my lambda function and my reactJs project.
Here is what my result is when I call options in postman on my API endpoint. Thus I do get the correct headers back so per my understanding my API is allowing CORS.
So after a very helpfull discussion with @Jannes Botis I found the solution.
In template.yaml I changed my values to:
Globals:
Function:
Timeout: 10
Api:
Cors:
AllowMethods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
AllowHeaders: "'Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers'"
AllowOrigin: "'*'"
MyAPIFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: myendpoint/
Handler: app.lambdaHandler
Runtime: nodejs12.x
Events:
GetMyData:
Type: Api
Properties:
RestApiId: !Ref MyApi
Path: /myendpoint
Method: get
Options:
Type: Api
Properties:
RestApiId: !Ref MyApi
Path: /myendpoint
Method: options
Auth:
ApiKeyRequired: false
Note: You will get error "No 'xxx' header is present on the requested resource." where xxx is either Access-Control-Allow-Methods, Access-Control-Allow-Origin and Access-Control-Allow-Headers, thus you need to add them in your AllowHeaders. Also note that you have to add an Options resource with ApiKeyRequired: false.
Then your response from your options and get request should have the same headers:
headers: {
"Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT",
"X-Requested-With": "*"
}
Note: 'Accept' MUST BE PRESENT otherwise you will get "Response to preflight request doesn't pass access control check: It does not have HTTP ok status.".
Your preflight must be able to pass a 200 OK when you ommit the x-api-key in postman.