Cross-Origin Resource Sharing. Avoiding Access-Control-Allow-Origin CORS error

JavaScript

In this article, we explain what Cross-Origin Resource Sharing (CORS) is and how to avoid errors associated with it and the Access-Control-Allow-Origin header. This includes describing it both from the viewpoint of the frontend and the backend.

CORS: Cross-Origin Resource Sharing

Cross-Origin Resource Sharing (CORS) is a mechanism allowing (or disallowing) the resources to be requested from another origin than it is served on. It is built into the browsers and uses HTTP headers to determine whether or not it is safe to allow a cross-origin request. When a web application requests a source with a different origin (origin includes a domain, a protocol, and a port) it is cross-origin. Browsers restrict such requests unless the response from the other origin includes the right headers.

Let’s jump straight into coding. We use a simple Express app here:

This, when running locally, opens the http://localhost:8080/posts endpoint.

So far so good. Now try to use Postman to perform a GET request.

Postman CORS Cross-Origin Resource Sharing Access-Control-Allow-Origin

A success! Let’s modify our app a little and add an additional endpoint:

This will give us an empty document at the  http://localhost:8080 address. Let’s open it in the browser, and in DevTools execute:

Devtools CORS Cross-Origin Resource Sharing Access-Control-Allow-Origin

Works fine as well!

In this example, we run our request in the same origin, but this is often not the case. Imagine creating a frontend app that runs in a different origin, for example on a different port. To create such a situation, let’s run an additional express app on a different port.

Now, let’s open our second app at the address http://localhost:4200 and try to perform the same fetch request.

Devtools CORS Cross-Origin Resource Sharing Access-Control-Allow-Origin

This results in an error:

Access to fetch at ‘http://localhost:8080/posts’ from origin ‘http://localhost:4200’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

As you can see, the request itself was successful, but the browser blocked it.

Conclusions

  • The first example includes us using Postman, so the CORS mechanism wasn’t involved
  • In the second example, we perform a request from the same origin, so the CORS mechanism didn’t block our request
  • The third example is a Cross-Origin request and therefore it is blocked.
    This does not need to be the case. As the error states, we can set the Access-Control-Allow-Origin header. You need to attach it to the response that the browser receives from the server.

Access-Control-Allow-Origin header

To specify what origins have access to the resource, you need to add the Access-Control-Allow-Origin header to your response. It will be interpreted by the browser of the visitor of your site.

While using Express there are a few ways to do that. The simplest one is to attach the header straight in the handler:

This will tell the browser that it is safe to request a resource from that origin.

Devtools CORS Cross-Origin Resource Sharing Access-Control-Allow-Origin

It works! But that means that you would have to call  setHeader in the every one of your handlers. This is where you can use middleware:

If you call the  use function, the callback you provide will be executed every time a request is sent to the server. It results in attaching the Access-Control-Allow-Origin header to all your responses.

Possible values

One of the possibilities is to specify an exact origin as we did in the previous example. If you choose to be specific, you need to all the way: browsers do not support multiple Access-Control-Allow-Origin headers. On the other hand, you can use a wildcard:

res.setHeader('Access-Control-Allow-Origin', '*');

This value tells the browser that the given resource can be shared with any origin. There is one catch though: when using a wildcard, you can’t send or receive cookies. If you try to do so, the browser throws an error.

Other ways to bypass the CORS policy

One way to override the CORS policy is to install an extension such as Allow-Control-Allow-Origin: *. It Adds the  Allow-Control-Allow-Origin: *  header to the all the responses that your browser receives. As mentioned above, it disrupts the way that cookies are sent and received, so keep that in mind.

Another thing you can do is to specify in your request, that you want to bypass the CORS secure mechanism. You can do it if you use Fetch API by setting  the mode parameter to no-cors:

This will work regardless of the Access-Control-Allow-Origin header. There is no equivalent of that in the XMLHttpRequest, unfortunately.

If you would like to know more about Fetch API and XMLHttpRequest, check out Comparing working with JSON using the XHR and the Fetch API

Summary

In this article, we explained what the Cross-Origin Resource Sharing (CORS) is, and how can we deal with it in terms of the origin access control. It included creating a simple backend express app and sending requests both from Postman and the browser to illustrate how the CORS works. Aside from that, the article provided tips on how to deal with this error by setting the Access-Control-Allow-Origin header, using browser extensions and an additional parameter that you can set in the Fetch API request. This can help you design both your frontend and backend while keeping the CORS mechanism in mind.

Leave a Reply

Your email address will not be published. Required fields are marked *