Eventually, in a developer’s life, you end up stumbling upon CORS. And it can be a pain. This morning I came across the following warning when trying to develop a new feature for a client:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://someweb.com. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

What is CORS?

I already had a faint idea of what it was, something along the lines of “you can’t request resources from other websites unless that website explicitly allows you to“, but I needed to dig deeper in order to understand what was going on. The definition from the MDN is:

Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.

How can I fix it?

After reading many resources for a while, I found there are mainly three solutions to CORS problems:

  1. Change the architecture of the application so the API call is made from the backend instead of the frontend.
  2. Use a proxy server to which you have access to make the call for you.
  3. Enable the destination server to accept CORS requests.

The reason why we could avoid CORS issues by making our API calls through the backend of our application is because the responsible of enforcing that requests are only sent from allowed domains is the browser. Therefore, we could actually make those same calls from tools like cUrl or Postman and still be able to.

The above also explains the second solution. If, instead of making any request through client-side Javascript (in other words, the browser), we make the request through another application (a proxy) and return the result, we avoid the issue. You might be thinking “But you’re still making an API call to the server, what about CORS issues there?”. The interesting part is that since the proxy is under our control, we can enable it to accept CORS requests from our client, which takes us to the third solution.

The third solution is no more than enabling the destination browser to talk to our application. Usually all HTTP servers are configured to talk to certain addresses, none or maybe all, in case it’s a public API. This is done by adding the Access-Control-Allow-Origin header to a apache.conf or .htaccess file. But let’s not dig into the details, since 90% of the times you will not be able to tamper with third-party APIs or they will be simply public.

Most of the time you will be either making the API calls from the backend or proxing them and only in the case that you control both servers, then it might make sense to tamper with the configuration to enable the dialoge.

Leasons learnt

Going back to the issue I encountered in the morning, after having done all this research, it happened that the CORS warning was being thrown by some other unknown part of the application not related to my feature and that I had simply forgotten to invoke my JS function.

I had drawn a completely awkward assumption based on not truly understanding the situation – I tampered with my application’s Apache server’s configuration, swapped from jQuery to XMLHttpRequest to fetch, tested the application in 3 different browsers hoping for different results… and all because I did not fully understand what was happening.

Resources

Cross-Origin Resource Sharing (CORS)
Reason: CORS header ‘Access-Control-Allow-Origin’ missing Fetch API
Working with the Fetch API | Cross-origin requests
Yet another option: JSONP
cors.io – Online free proxy