Fixing CORS errors with Angular CLI proxy

Damilare A. Adedoyin
Level Up Coding
Published in
4 min readJun 16, 2020

--

source: Memegenerator.net

Trying to access an API endpoint while building on localhost can be traumatizing, especially when this error “No ‘Access-Control-Allow-Origin’ header is present on the requested resource” comes up. Don’t worry it wasn’t your fault, the error is due to the same-origin policy that is implemented by most browsers.

The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin. — source

The reason you are getting the error is because you’re making a request to a different origin from the one you’re currently on. Take for example, your application is running on http://localhost:4200 when you’re trying to access the resource from https://api.spotify.com/v1. localhost and api.spotify.com are two different origins which are also running on different protocols http and https respectively, this is a cross-origin request, and it’s enough reason for your browser to fume about you flaunting its rules. If the server had specified your origin in its header, you also won’t be facing this challenge.

What can we do about it?

Photo by Olav Ahrens Røtne on Unsplash

Using a Proxy

You may not always have access to the code running on the server. In this case, what you can do is to set up a proxy for your angular application. The Proxy basically attempts to fool the browser, it does this by pretending to have the API on the same origin whereas underneath the hood it's accessing the resource from another origin. This way the browser would be able to believe the same-origin policy is being adhered to, thereby taking out the CORS error.

How do we achieve this, let’s get into it right away.

Step 1:

Create a proxy.conf.json file and copy the following code into it.

A few things to note here:

  1. "/api” property of the object specifies the route for the proxy and the nested object specifies the configuration. Hence in order to make requests, the url will be http://yourhost/api (for my project, that would be http://localhost:4200/api).
  2. “target” property of the nested object specifies the API url you’re trying to reach, in this case spotify.com.
  3. “secure” property is used to specify whether the target is being served over http or https. It is currently set to true because the spotify.com endpoint is being served over https.
  4. “changeOrigin” property specifies that the target is on another domain different from that which the app is currently running on. In this case, it is set to true because the application is running on localhost while the target is on spotify . If they were both on localhost then it would be false.
  5. "pathRewrite" property allows you modify how the application interacts with the target. Without the “pathRewrite” property, every call to the proxy url http://localhost:4200/api will correspond to https://api.spotify.com/v1/api . This wouldn’t be a problem if spotify has an api endpoint, but since in reality they don’t provide such endpoint, this would lead to an error. Hence, setting the "pathRewrite" nested object with “^/api”: “” helps remove the unwanted “api” at the end of the url. This in turn ensures that calling http://localhost:4200/api will correspond to https://api.spotify.com/v1 .

Step 2:

Set your application to work with the proxy using either of two methods:

  1. By running ng serve --proxy-config proxy.conf.json Ensure that the proxy.conf.json file is created at your base directory.
  2. The other option is to modify the angular.json file and add the following lines of code to the architect configuration object.

A few things to note:
The serve property is already preconfigured in your angular.json file, the only addition you need to add is on line 5.

Once this has been added, run ng serve to start your application.

On production environment

I found it easier to create the proxy server on Nginx. Unfortunately the configuration of the Nginx server is beyond the scope of this article, I’d write about it on another post.

Other approach

If you have access to the server running the endpoint, you can simply add Access-Control-Allow-Origin: * to your header to allow all origins or you can add Access-Control-Allow-Origin: http://localhost:4200 to allow only requests from the localhost.

Photo by Alex on Unsplash

Further reading

Same origin policy

Cross origin request sharing (CORS)

Angular — Proxying to a backend server

Access control allow origin

Please drop your comments, questions or feedback in the comment section below and I’ll reply as soon as possible.

Also, if you made it this far please keep going and drop a clap or two. That would really make my day. :).

--

--