22

I have created an API endpoint with Serverless(serverless.com) which I expose through API Gateway. I'm getting following error though I have enabled CORS from the

XMLHttpRequest cannot load https://xxxxxxxxx.execute-api.us-west-2.amazonaws.com/development/signup. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://yyyyyyyyy.com.s3-website-us-east-1.amazonaws.com' is therefore not allowed access.

AWS API Gateway settings for the endpoint

I don't get any errors when I use Postman to make requests, despite I have set origin header or not. How can I fix this problem?

Milindu Sanoj Kumarage
  • 2,714
  • 2
  • 31
  • 54
  • postman does not take care about CORS, then if CORS are not enabled postman still handle the request, but the browser doesn't allow the api call if CORS are not enabled. – Cristian Sepulveda Aug 23 '17 at 16:52

9 Answers9

15

We have a bug right now where failed requests to API Gateway won't include the appropriate CORS headers, which masks the actual error on the request.

I'd add to what Ken said and make sure you've thoroughly tested the API and resources in the console and also on the deployed version using Postman or some other client that isn't a browser. I expect there is an issue with the API itself and that your CORS configuration is correct.

jackko
  • 6,998
  • 26
  • 38
  • 1
    I too realized this, used an Chrome extension to enable CORS and found the actual error. But now it is fixed, web page works like a charm when CORS Chrome extension is 'On'. But still getting this `No 'Access-Control-Allow-Origin' header is present on the requested resource.` error when CORS Chrome extension is 'Off'. And I still don't see any 'Access-Control-Allow-Origin' in response header. I get the expected output on Postman too. – Milindu Sanoj Kumarage Dec 18 '15 at 05:16
  • 1
    I also recommend you look at the actual response in the browser. In Chrome, under the Network tab. This can give more details on the error – Jason Apr 20 '16 at 03:35
  • @jack-kohn-aws, just hit something similar, has it been fixed? It was posted months ago – Ákos Vandra-Meyer May 18 '16 at 14:00
  • @Jason your tip was a big help. I was getting this error, but it was masking a bad request underneath. Thank you. – Pompey Magnus May 19 '16 at 03:13
  • 3
    I just spent an hour trying to figure out why your document didn't work, and it wasn't actually your document's fault, it was that I didn't Deploy the API afterward. Can you consider putting that in your document: http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html – turiyag Jun 01 '16 at 20:28
  • As suggested above, my reported "No Access-Control-Allow-Origin header" error was actually being caused by a misconfigured request - in my case sending a Javascript object rather than JSON representation of same. So definitely follow the advice above - check out everything in dev tools. You may see an underlying issue. – Adrian Parker Aug 31 '16 at 04:32
  • Must re-deploy api gateway for changes to take effect as @turiyag noted. – Doug Apr 15 '17 at 14:45
  • Just to note: we released an update to the service to correct the bug noted by Jack: http://docs.aws.amazon.com/apigateway/latest/developerguide/customize-gateway-responses.html – Bob Kinney Jun 07 '17 at 16:16
6

As Jack Kohn pointed out the AWS console does not add the CORS headers on non 200 response, and apparently does not allow you to add any custom header.

I was able to enable CORS headers on failed request by exporting to swagger and manually editing the file (Just copied the 200 response) and importing it back.

The responses should look like this:

  responses:
    200:
      description: "200 response"
      schema:
        $ref: "#/definitions/Empty"
      headers:
        Access-Control-Allow-Origin:
          type: "string"
    401:
      description: "401 response"
      schema:
        $ref: "#/definitions/Empty"
      headers:
        Access-Control-Allow-Origin:
          type: "string"
  x-amazon-apigateway-integration:
    responses:
      default:
        statusCode: "200"
        responseParameters:
          method.response.header.Access-Control-Allow-Origin: "'*'"
        responseTemplates:
          application/json: "__passthrough__"
      Authentication Failed.*:
        statusCode: "401"
        responseParameters:
          method.response.header.Access-Control-Allow-Origin: "'*'"
        responseTemplates:
          application/json: "__passthrough__"

Hope this helps.

Tiago Lopo
  • 7,619
  • 1
  • 30
  • 51
6

I was struggling with the same issue when 'POST' to API Gateway. But I found the fix for the issue.

After enabling CORS for the method resource, and after adding the necessary Headers e.g. 'Access-Control-Allow-Origin' = '*' wildcard, and it still fails.

Go to OPTIONS of that resource you are invoking, 'GET', 'POST', etc..click the "Method Request" pane of that resource, set API Key = FALSE, do NOT have the API Key set to true. This will cause the CORS error.

Reason, OPTIONS is technically not a method, it a browser function to execute the Preflight request, thus during the Preflight the browser does not know what API key to send, it will know only know after the response is return to the browser of 'Access-Control-Allow-Origin' = '*' then it will look up the code for the HTTP req to setHeaders of the X-Api-Key = some value.

Note: the invoke method itself, 'POST', etc.. can have the API Key = True, which is perfectly fine.

Hope this help those who are struggling as I did for a while :)

Michael Tung
  • 61
  • 1
  • 3
4

I would start troubleshooting by inspecting your API in the AWS Console to make sure serverless registered everything the way you expect.

  1. Load the AWS Console and navigate to the API Gateway service.
  2. Click the API to open it up.
  3. Find your /signup resource
  4. Make sure you see the OPTIONS method under /signup
  5. Click each resource including options and check the following:

    a. Click Integration Response, click the arrow in the first row of the table for 200 to open it up.

    b. Click the arrow to open Header Mappings

    c. Make sure you see Access-Control-Allow-Origin mapped to '*'

If you find this header missing from one of the methods a quick fix is to click back on the /signup Resource and click the Enable CORS button. AWS will build out OPTIONS and the header mappings on all methods for you. Of course you still need to figure out why serverless didn't set things up for you but this will at least get you going.

Another note about the Enable CORS button, if you add another method later you'll have to click it again to re-run the tool to setup your new method with CORS.

kennbrodhagen
  • 4,258
  • 2
  • 26
  • 21
  • 2
    These is an OPTIONS method with `Access-Control-Allow-Headers : 'Content-Type,X-Amz-Date,Authorization,X-Api-Key'`, `Access-Control-Allow-Methods : 'POST,OPTIONS'` and `Access-Control-Allow-Origin : '*'` set. And I see Access-Control-Allow-Origin mapped to '*' in my POST. I tied Enable CORS buttons several times. – Milindu Sanoj Kumarage Dec 17 '15 at 22:15
  • 1
    "Another note about the Enable CORS button, if you add another method later you'll have to click it again to re-run the tool to setup your new method with CORS." - This is the key for my problem. – DccBr Aug 24 '16 at 19:52
2

I had near the same problem,as i posted in another question, I needed to add the following headers to my response:

headers: {
            'Access-Control-Allow-Origin' : '*',
            'Access-Control-Allow-Headers':'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Credentials' : true,
            'Content-Type': 'application/json'
        }

And , according to this documentation:

http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

When you use proxy for lambda functions on API Gateway config, the post or get methods have no added headers, only the options method does. You must do it manually in the response(server or lambda response).

Beside that, I needed to disable the 'API Key Required' option in my API gateway post method, as someone here already said.

2

I have the this problem...I enable CORS, the Test work as it is sending the headers, but when I call it from my app it fails and no headers found on the response.

it is because after set CORS you have to DEPLOY the API. I Deplyed the API and everything works great.

Cristian Sepulveda
  • 1,572
  • 1
  • 18
  • 25
1

If you are using AWS lamda, set response headers as follows. Configuration on API Gateway only will not work

headers: {
            'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*',
        },
prakashpoudel
  • 565
  • 2
  • 9
  • 25
0

You need to enable CORS for all the methods. Means, you need to add below three headers for all your methods

            "headers": {
            "Access-Control-Allow-Origin": {
                "type": "string"
            },
            "Access-Control-Allow-Methods": {
                "type": "string"
            },
            "Access-Control-Allow-Headers": {
                "type": "string"
            }
        }

It is tedious task to add these headers to all your methods in JSON.

Created a utility in Java which automatically adds these headers to Swagger JSON. You can run it before importing it to API Gateway and import the output JSON which has CORS enabled in all the methods

https://github.com/anandlalvb/SwaggerToAPIGateway

I hope this utility may help anyone looking for this to do it easily.

binary
  • 1,364
  • 1
  • 15
  • 20
0

I am using AWS sdk for uploads, after spending some time searching online i stumbled upon this thread. thanks to @lsimoneau 45581857 its turns out the exact same thing was happening. I simply pointed my request Url to the region on my bucket by attaching the region property and it worked.

 const s3 = new AWS.S3({
 accessKeyId: config.awsAccessKeyID,
 secretAccessKey: config.awsSecretAccessKey,
 region: 'eu-west-2'  // add region here });
davyCode
  • 399
  • 4
  • 4