Ok so this isn’t a new thing, but most developers have been thwarted by this at some point for anyone finding this I’m going to explain it in plain english as I’ve lost count of the times I need to explain these issues to someone, or yourself 🙂
- CORS is a browser thing, that means using Postman, Curl whatever other means your doing a http request your only going to experience the problem in a browser as other tools do not respect CORS.
- Simply put it’s a set of rules that are checked by the browser in the response headers of a request, these rules determine which websites are allowed access to the resource.
- It does not care what framework (Angular,React,Jquery) or Vanilla JS your using to make your request, CORS issues are generally down to how it’s configured on the resource (the server) your querying.
So when making a request the browser checks what headers the server returns, this can happen before the actual request is sent in something called a pre-flight request (more on that later).
For example I make a POST request from website.co.uk to domain.co.uk and the server returns
In this case only domain.co.uk is allowed to access this resource.
Another example would be that it returns:
This means anyone can access this resource. Read more below for info on setting these headers and what a pre-flight request it.
The other typical CORS issue is related to the methods
Here only the POST method is allowed, trying to PUT or DELETE will not work, you need to configure your server (see below) on how to enable this.
What exactly is CORS for?
CORS protects the end user the client YOU from a third party making requests on your behalf that originated from a different website than the one your on it does this by checking the Origin of the request to validate where it came from, if it’s still not making sense then, there’s some more detailed examples on Stackoverflow
What is a Pre-flight request?
So many posts i’ve seen where Angular, Jquery etc describe this as a feature of the library, wrong again it’s the browser doing this not your JS library!
Pre-flight is when the browser sends an OPTIONS request before your actual request gets sent, which the server typically responds with the options available e.g POST, PUT etc.. along with that in the headers will be Access Control rules.
Here’s an example
As you can see the response details what methods, headers and origins are allowed in the response headers.
If your website is not in the Access-Control-Allow-Origin: part or it’s not * that means your not allowed and it will not make your actual request and instead will return an error like:
Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
You might be asking, why don’t you see pre-flight on my request? Well this only happens for what is deemed a non-standard request.
The first part of the spec explains this https://www.w3.org/TR/cors/
It gets slightly more complicated if the resource author wants to be able to handle cross-origin requests using methods other than simple methods. In that case the author needs to reply to a preflight request that uses the
OPTIONS method and then needs to handle the actual request that uses the desired method
Simple is GET, HEAD, POST without additional headers so any header modification will result in a pre-flight request.
Configuring your server to allow CORS
By default most server software e.g Apache or similar will block cross site requests, and you will need to modify the rules in your .htaccess or .conf
Apache example using .htaccess
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "accept, origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Typically the above will resolve CORS issues whilst using JS ajax requests, be careful as to what methods you need to allow.
But what are the consequences of doing this?, well there’s a good reason it’s not allowed by default see above “What is exactly is CORS for?”. Short answer is that you would generally have other protections in place for example a custom header that is submitted along with the request that only the client and the server know and you would also most likely wan’t to allow access to only a select few e.g
Access-Control-Allow-Origin: http://www.webapp.com, http://www.webclient.com
Using the above safegaurds it’s generally ok to enable it.