You must have come across a situation where in you build a UI and connect to a remote API to fetch some data. The API works fine when accessed through postman or other rest client but when your UI calls the API, it fails. Why that happens?
If you closely look into the error log in browser, you will get some CORS errors. What are these CORS errors and why it happens?
Lets see in detail about the source of these errors and some of the ways to resolve it.
What are CORS Errors?
CORS stands for Cross Origin Resource Sharing. It is a security feature where in the web application restricts the access to a resource (In our example, it is API) from outside domains. This mechanism is built in browsers and that’s why the error comes when front end tries to access the API. This is because UI (javascript, angular, react) runs in browser and it is easy to modify the JavaScript and send a malicious request to the API which can lead to security threat.
A cross-origin request example can be a the front-end JavaScript code from https://domain-a.com
uses XMLHttpRequest
to make a request for https://domain-b.com/data
.
How CORS works?
Lets see how CORS works. Browser sends cross site requests using XMLHttpRequest. There are three types of CORS requests which will discussed here:
Simple Cross Site Requests: These requests have following properties
1. HTTP methods should be of type GET, POST, HEAD
2. Content-Type should be one of the below
application/x-www-form-urlencoded
multipart/form-data
text/plain
3. No custom header should be added to the requests other than automatic headers set by user agent.
For these requests, we can send the response with header Access-Control-Allow-Origin: *. This is helpful in the scenario where the resource needs to accessed from multiple clients.
But if the resource is restricted for particular credentials or can be accessed only from specific domains(eg http://domain-a.com), then we have to add those domains in allowed origins. Below is the correct configuration:
Access-Control-Allow-Origin: http://domain-a.com Access-Control-Allow-Credentials: true
Preflight Requests: These are the requests with below properties
- HTTP methods other than GET OR POST.
- POST Request with content-type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain
- A custom header is added to the request.
For these requests, HTTP OPTION request is sent before actual request. This request is a kind of security check done by browser by asking API who is allowed to access what. So if the server sends a successful response to this OPTION request, then only actual request will be intitiated.
Along with the success response, server sends some headers in the response which shows what all requests are allowed by server. Below is the screenshot of an OPTION Response header by server
// TO DO attach screenshot
Server should do following configuration
Access-Control-Allow-Origin: http://domain-a.com | * Access-Control-Allow-Methods, Access-Control-Allow-Headers should be configured
Credentialed requests: Requests which contains cookies or Authentication headers. For these kind of requests server should configure following:
Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: http://domain-a.com (* will not work)
Hope this explains in details how CORS works and what are the different workaround to resolve CORS errors in your application.
Also read
HOW TO ENABLE CROSS ORIGIN REQUESTS TO ACCESS REST API IN SPRING?