I wanted to access a API Gateway via JQuery, but every time I tried to post something, I got an error:
Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.
Not very helpful, actually, but let’s try to understand what is happening.
When you are in a given site (www.a.com) and want to perform a Ajax POST / GET to another server (api.gateway.com), the service in api.gateway.com needs to have some called CORS (Cross-Origin Resource Sharing) enabled, as a security measure. There’s a whole protocol for that, and you can read more information about it on the link above.
Enabling CORS in API Gateway
AWS has CORS support, that you need to enable in your API. To do that you need to perform these steps:
- Go to AWS Console
- Go to API Gateway
- Click on your API
- Click on the method that you want to enable CORS on
- Open the menu and click on Enable CORS
- You will be asked for a couple of parameters. If you want to enable it for everyone, you can just leave this as default and click Enable CORS and replace existing values. You can read more information about the different parameters in the official guide
- Now you need to deploy your URL. Just go to Stages → Create (or use an existing Stage that you already have) and you will get an URL similar to this one
- You are going to post to that URL
Now, to use JQuery to call to this API has a couple of tricks that you will need to keep in mind
- You can’t use $.post to perform the POST. This is because the $.post is a shortcut without parameters that we need to set. You need to use $.ajax
- You don’t need to change the headers to include anything; all you need is part of the parameters.
The important parts
- Type: use the type that you defined in your API Gateway (POST, GET, DELETE, etc.)
- crossDomain set to TRUE (this will set the expected headers)
- contentType set to “application/json” if you set it like that in your API Gateway
As a security measure, you should avoid setting * as Origin the API Gateway. Sure, you can do it while you develop, but once you go to PROD, you should only allow the sites that should have access to it.
The other thing to consider is that this test does not include anything related to security: it was an open API, and everyone could call it having the correct URL. So should always implement security tokens, or any other mechanism in the calls, to make it secure. You can find some suggestions in the Official AWS Guide. Remember that they are crawlers and bots that will scrape your URLs and will try to get access to it.