How to fix CORS Errors?
We all have encountered CORS errors in web-app development, in this article, we will understand what are these errors, what causes these errors in the first place, and how to fix these errors.
Before fixing the issue, in order to understand CORS Errors, we first need to understand what are origin and cross-origin. ORIGIN is the website identifier you are visiting currently. Origin is schema i.e. HTTP/HTTPS plus hostname. Cross-Origins Requests are requests originating from an origin for a different origin.
CORS stands for Cross-Origin Resource Sharing, these are a set of standards that governs how cross-origin requests should behave. Let's take an example to understand why CORS error occurs? Say, a website apples.com
makes an API request to oranges.com
, this will result in a CORS error, as the browser knows that the current origin is https://apples.com
and there should not be requests made to oranges.com
in normal conditions. In such a situation, the browser makes a pre-flight call which is an OPTIONS call.
Please note, that it is the browser that is detecting cross-origin requests and makes a preflight request. So old versions of chrome, internet explorer, or firefox may not even care about the cross-origin requests and may fire the request straight away. As a matter of fact, CORS can be disabled from the modern browser also, and there are extensions to do so. However, this is not recommended as CORS is a security feature.
CORS is actually a feature, not a bug.
Let's continue what happens after the browser makes the pre-flight request call. organges.com
server receives the request from a different origin and now it has to decide if it wants to allow traffic from apples.com
or not. If oragnes.com
decides not to serve the request, the browser throws the CORS error. Now, in order to handle the pre-flight request, special headers are sent by the both client and recipient server during request and response respectively. Let's take a look at those special headers.
Client Request Headers:
- Origin: The
Origin
request header indicates the origin (scheme, hostname, and port) that caused the request. - Access-Control-Request-Method: This header is used by the client to let the server know which HTTP method will be used when the actual request is made. This header is necessary as the preflight request is always an
OPTIONS
and doesn't use the same method as the actual request. - Access-Control-Request-Headers: This header is used by the client to let the server know which HTTP headers the client might send when the actual request is made.
Server Response Headers:
- Access-Control-Allow-Origin: This response header indicates whether the response can be shared with requesting code from the given origin. In our example, if
oranges.com
wants to support calls fromapples.com
, it can send this header asAccess-Control-Allow-Origin: https://apples.com
. This is normally set as a regex to support sub-domains as well. - Access-Control-Allow-Method: This header specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above. For example,
Access-Control-Allow-Method: GET, POST
. This is the complementary header for clientsAccess-Control-Request-Method
header. - Access-Control-Allow-Headers: Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. This header is the server-side response to the browser's
Access-Control-Request-Headers
header. This is the complementary header for clientsAccess-Control-Request-Headers
header.
Let's look at client-server interaction with pre-flight request fired first, and upon receiving 2xx for OPTIONS
request with headers value set, the main request is fired.
Custom CORS Handler:
Now, we know why CORS happens and in order to fix it, the recipient server needs to respond with certain headers. Most of the languages and frameworks have tons of packages/libraries doing this for us. But if we need to implement something of our own, we can write a middleware for doing so.
from http import response
def cors_handler(request, *args, **kwargs):
if request.method == 'OPTIONS':
return response(
headers = {
"Access-Control-Allow-Origin": "https://apples.com",
"Access-Control-Allow-Method": ["GET", "POST"],
"Access-Control-Allow-Headers": request.headers["access-control-request-headers"]
},
status = 204
)
If we put the above piece of code in oranges.com
server, then requests coming from apples.com
would be allowed for GET
and POST
requests and it will not result in a CORS error.
Conclusion:
So, in the article, we understood why CORS Errors happen and how we can fix them. Remember that CORS error is a security feature built-in in modern-day web browsers and the same problem won't arise if let's say you use some client like Postman. So next time you encounter the CORS error, instead of getting frustrated, just set the headers as per your requirement and the CORS error will be handled.