Cross-Origin Resource Sharing (CORS) is a browser security feature designed to prevent malicious websites from interacting with APIs or resources from another domain. While it enhances security, it can become a serious hurdle during local development, especially when frontend and backend services run on different ports or domains.

In this article, we’ll break down what CORS is, why it causes issues during local development, and explore a variety of techniques to bypass or handle CORS errors effectively.


Understanding CORS

CORS is enforced by web browsers for cross-origin HTTP requests. A request is considered cross-origin if:

  • The protocol (http vs https),
  • The domain (example.com vs api.example.com), or
  • The port (3000 vs 8000)

…differs between the frontend making the request and the backend receiving it.

Common Localhost Scenario

Your app runs on:

http://localhost:4200

Your backend server runs on:

http://localhost:8000

Any fetch or XMLHttpRequest from 4200 to 8000 is a cross-origin request (because the origins are different, the combination of protocol, host and port define an origin), triggering a CORS preflight (OPTIONS) request in many cases.

If the backend doesn’t return proper CORS headers, the browser blocks the call.


Bypass Technique for Local Development

Custom Reverse Proxy Server

You can create a proxy server in Node.js that forwards requests to your API, effectively avoiding CORS. For this method to work you also need to take the actual URL of the site that the backend or the API is expecting and add it in your hosts file so that it points to the localhost (remove or comment out this entry after you are done with the development and uncomment this entry again when you are doing the development). The hosts file is located at /etc/hosts and on Windows environments it will be located at C:/Windows/System32/drivers/etc/hosts

#/etc/hosts file

127.0.0.1 example.com
127.0.0.1 www.example.com

After you have entered the URLS of your website in the hosts file you need to create a key and a cert file in order to sign the local SSL certificates. These days almost all browsers expect the requests to be coming from HTTPS endpoints and the CORS check fails in case we don’t run our local site on HTTPS. To generate the key and the cert open the terminal (Git Bash in my case) and type this:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

After generating the public and private key files you need to create a new folder and create a new .js file with the following content in it:

//proxy-server.js

const fs = require('fs');
const https = require('https');
const httpProxy = require('http-proxy');

// Load SSL certificate
const options = {
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
};

// Create a proxy server
const proxy = httpProxy.createProxyServer({});

// Create HTTPS server and listen on port 443
const server = https.createServer(options, (req, res) => {
  proxy.web(req, res, { target: 'http://localhost:4200' });
});

server.listen(443, () => {
    console.log('HTTPS Proxy server running on port 443 and forwarding to localhost:4200');

Run the below commands to start the above server:

npm install http-proxy
node proxy-server.js

Now when you open https://example.com in your browser it forwards HTTPS traffic to your local server running at localhost:4200 (HTTP) and it solves the CORS issue.


Testing and Debugging CORS Issues

  1. Browser DevTools → Check the Network tab for:
    • Status code 200, but response blocked
    • OPTIONS preflight and missing Access-Control-Allow-* headers
  2. Inspect Server Logs → See if OPTIONS requests are hitting the server.

Common Pitfalls

  • CORS is enforced by browsers only. If you use curl, Postman, or server-to-server calls, CORS doesn’t apply.
  • Missing OPTIONS handler on backend → Causes 405 Method Not Allowed.
  • Wildcard origin () doesn’t work with credentials.

Conclusion

CORS is a necessary security constraint, but it can be frustrating during development. Fortunately, there are several clean and effective workarounds. The best method is always to enable CORS on the backend, but when that’s not feasible, frontend proxying or reverse proxies offer flexible alternatives.

By understanding the cause and applying the right technique for your context, you can eliminate CORS headaches and accelerate local development.

Leave a comment