Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
692 views
in Technique[技术] by (71.8m points)

javascript - Fix CORS "Response to preflight..." header not present with AWS API gateway and amplify

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. enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...