Resolve CORS Errors Once and For All: Three Methods

The Three Approaches for Resolving CORS Errors

Stephen Biston
6 min readNov 8, 2023
CORS Diagram from https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Dealing with CORS

If you’re reading this, more likely than not you have encountered a CORS error when testing some web code you’re writing and you’re not sure what to make of it. The error is thrown when your code makes a request to a server, and the error probably looks something like this:

Access to fetch at 'https://<target website>' from origin 'https://<your website>' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

There’s good news! These errors are common, straightforward, and simple to resolve. You need only to remember that CORS errors are browser errors and not an error with the endpoint you’re requesting.

Why Do I Get This Error?

CORS errors can be very frustrating, especially when they appear to crop up out of nowhere. A web app in development can be working totally fine one day, and then maybe the next day you decide you want to split the frontend from the backend, and suddenly all of your requests to your own backend start failing.

CORS errors are thrown when a web request is made in the browser to an endpoint on a domain that is different from the domain of the webpage making the request.

That’s why, for example, if you have a project with a unified frontend and backend served on, say, localhost:8000the frontend can make requests to the backend without any issues or special treatment. If the frontend and backend are then split up, however, and the backend remains on localhost:8000 while the frontend is served from localhost:9000 now the browser considers those different domains and it will throw CORS errors.

That last bit is important — it’s all up to the browser.

Say it with Me: CORS Errors are Browser Errors

A common point of confusion for newer devs encountering CORS errors surrounds the disclarity around what is actually responsible for the error: the client (browser) or the server?

Fortunately, it’s pretty simple: it’s always the client! CORS, or Cross-Origin-Resource-Sharing, is an exclusively browser-owned concept that the server has no direct control over. Now, as we’ll cover, you can resolve this error on the server side of things by returning a response the browser likes, but ultimately it is the browser that enforces the rules and throws the errors.

The dirty details of what CORS is and all its variations are outside the scope of this post but in simple terms, CORS seeks to create rules around which web pages can request content from a given domain. To achieve that, browsers require that servers supply specific headers that indicate their willingness to respond to requests originating from domains other than their own. Remember that message in the CORS error above?

No 'Access-Control-Allow-Origin' header is present on the requested resource.

That Access-Control-Allow-Origin header is the very header that the browser is looking at to understand if the server wishes to allow requests from other domains! By default, servers won’t return any Access-Control-Allow-Origin headers which means that the browser will, by default, block cross-origin requests.

Side note: Bypassing CORS Outside of the Browser

A natural consequence of understanding that CORS errors are owned by the browser is the realization that any request that fails to a CORS error in the browser will succeed if requested outside of the browser. I recommend using thecurl command line tool to test your requests outside of the browser, I bet you they’ll succeed! See https://curl.se/.

Resolving CORS Errors

There are three simple approaches to resolving this issue and allowing your requests to be completed successfully.

Make Your Domains (Origins) Match

One of the most common patterns for resolving these issues is to simply avoid the issue entirely by ensuring that there is no sharing of cross-origin resources by configuring your servers such that your frontend and backend(s) are served from the same domain. The frontend may be served at the domain root and then backend resources under a subpath, for example /api/ .

This approach is a bit trickier locally, especially if you’re not using additional webserver software like nginx as you might be in production to handle routing requests from a single local domain to different servers.

For a contrived example, you could run your backend server at localhost:8000 , your frontend server at localhost:9000 and run your nginx server at localhost:5000. Then if you configure nginx to serve all requests to the /api/ path from locahost:8000 and all other requests from localhost:9000 then you would have a unified local domain at localhost:5000 that would no longer yield CORS errors! If all that sounds like a lot of work for a local environment, you’re right, which is why most local environments use the next approach.

Return an Access-Control-Allow-Origin Header

This is the easiest, most direct, solution, and in my opinion the most appropriate for local testing. If you have control over the server that is causing your browser to throw CORS errors, you can update that server to return the Access-Control-Allow-Origin header that the browser wants. The specific implementation will be different for each web server framework but the idea is simple and not any different from returning any other HTTP header. The header will look something like this:

Access-Control-Allow-Origin: '*'

That will allow cross-origin requests from any and all origins. Or, alternatively, if you wish to be a bit more specific you can return something like this, assuming localhost:9000 is the origin that your requests will come from:

Access-Control-Allow-Origin: 'http://localhost:9000'

Read more about the details of this header here.

Make Your Requests Outside of the Browser

This approach is the most foolproof, and a great tool to have in your toolbox as a developer, but also the most involved.

This comes up most often when you need to make requests to an API controlled by a third party. If you don’t own the endpoint in question you can’t change its domains or force it to return an Access-Control-Allow-Origin header — but you can avoid making the specific request that is throwing the CORS error within the user’s browser. CORS errors can essentially always be worked around by using a proxy to make the request for you.

If you’re not familiar, a proxy server is just another server that is responsible only for forwarding a request to another server and returning the result. In this case, we would make the proxy server responsible for forwarding the request to the third-party endpoint for us, and in that way, the request would be made outside of the context of the browser, and thus CORS restrictions would not apply. Since the proxy server is under our control we’d have the ability to configure it to return the appropriate Access-Control-Allow-Origin header so we could then make our request to the proxy server from the browser without issue.

There are many different ways to proxy a request, but ultimately it’s just as simple as mentioned before — a means to forward a request to another server and return the result. I’ve done this by creating small AWS Lambda functions, or even by creating one-off endpoints on my existing application that proxy the request — it doesn’t even have to be a whole separate server! Anything works, just so long as you make the cross-origin outside of the browser.

Further Reading

--

--

Stephen Biston

Web Dev & Technical Lead with over a decade of experience. Did my content help you out? Feel free to buy me a coffee: https://ko-fi.com/stephenbiston