Make a request between frontend and backend locally running on different ports without CORS issue
Tags: webdev, frontend, nginx, backend
Published: 2019-06-17 11:36:35

---
title: Make a request between frontend and backend locally running on different ports without CORS issue
published: true
description: Make a request between frontend and backend locally running on different ports without CORS issue. 
tags: webdev, frontend, nginx, backend
---

Whenever you run frontend and backend in the same system in 2 different ports, you may soon find yourself facing a CORS error.

####What is CORS?
From MDN
>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 executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.

####What is an Origin?
>Web content's origin is defined by the scheme (protocol), host (domain), and port of the URL used to access it. Two objects have the same origin only when the scheme, host, and port all match.

For e.g: If you make a request for a resource in www.xyz.com from www.abc.com site, it leads to a call for CORS by the browser since the origin is different.

###Running both frontend and backend servers locally:

When running a project locally on your system, you may have to start servers of both frontend (like nodejs etc..) and backend (like python, go-lang etc..). To run these two servers on same system you need to have two different ports assigned to them. (since one port at a time can only accommodate one process).

For e.g frontend server can be running on localhost:8001 and backend server on localhost:8002.

Whenever we make a request from localhost:8001 (frontend) to  localhost:8002 (backend), since they both are two different origins, leads to a CORS issue. How to solve this issue?

Some ways of handling this:

1) **Server side**: check <a href=https://enable-cors.org/server.html>this</a>. Use "Access-Control-Allow-Origin" headers in response from various servers to tell the browser that the current request for cross origin is allowed. (remember CORS is the way of telling browser using http headers that the cross origin request made for the resource is fine and can be allowed)

2) **Client side**: check <a href=https://www.html5rocks.com/en/tutorials/cors//>this</a>.

3) **Using Reverse Proxy**:
I have explained what is a reverse proxy <a href=https://dev.to/nikhilponnuru/understanding-proxy-reverse-proxy-vpn-load-balancer-and-more-2p98> here </a>. Do check it out before reading further.

I feel using a reverse proxy like Nginx is a pretty neat solution than the above two ways. 

###Steps to use reverse proxy for this usecase:

I have tried and tested the below steps using Nginx.


step 1) Run the frontend at say port 8001.

step 2) Run the backend at say port 8002.

step 3) Let's say all the backend requests are separated from frontend URL's by '/api/' or any other such seperation.

step 4) Run the reverse proxy at a port say 8000

Sample Nginx configuration: server block

```   
server {
        listen       8000; 
        server_name  localhost;
        location / {
	   proxy_pass http://localhost:8001;
        }
        location /api/ {
           proxy_pass http://localhost:8002;

        }
}
```

If you are not familiar with reverse proxy, check my <a href=https://dev.to/nikhilponnuru/understanding-proxy-reverse-proxy-vpn-load-balancer-and-more-2p98>post</a> explaining it.

Now the beauty of using a reverse proxy is you can run the frontend and backend at the same port 8000. But didn't we learn that a single port is bound to one process? well whenever you make a request to the endpoint with `localhost:8000/api/*`, the reverse proxy redirects it to 8002 (backend) and all requests without '/api' are redirected to 8001 (frontend).

This solves CORS issue since the origin is same, which is 8000 here.