Why you're here?
You are developing a frontend and running a development server, your server is running on your localhost interface on port 8080. In order to develop the frontend app you need the api from localhost running on port 8000.
You write your frontend code and an set the api endpoint to http://localhost:8000/api/v1 and you access you frontend dev server http://localhost:8080/. Notice that the difference in ports.
When you visit the frontend you get an CORS error. Your browser protects you agains yourself.
Why does this happen?
How to solve this?
There are ~~2 elegant ways~~ 4 elegant ways to solve this.
Use a browser plugin
Firefox: Corser plugin
For firefox there is CORS Everywhere, but it has a problem. If you enable that plugin you will have to be carefull when you will have it enabled or disabled. You can use Corser that has domain rules where you whitelist the domains you want to use https://addons.mozilla.org/en-US/firefox/addon/corser/
Chrome: Allow-Control-Allow-Origin: * plugin
For Chrome there is Allow-Control-Allow-Origin: * plugin.
Add a header to the API
In your framework for every API response add a header Allow-Control-Allow-Origin: * .
Configure the development tools to proxy the API calls
Depending on your stack you can configure the frontend development server to proxy the /api requests to another server.
This depends on your frontend stack. If you use webpack as packaging, you can use webpack-dev-server.
But what to do if your development server does not support this?
Use traefik as a proxy
I recently discovered a Golang reverse proxy called Traefik. It has some neat features:
- it's distributed as staticaly compiled ELF
- it can be dynamicaly configured with common container orchestrators (Kubernetes, Swarm ...), api and files
- simple TLS/SSL certificates with ACME (Let's encrypt)
You need to do 3 steps:
Download traefik from https://github.com/containous/traefik/releases
Create configuration file traefik.toml
Create the folowing configuration:
[entryPoints] [entryPoints.http] address = ":9000" [file] [frontends] [frontends.spa] entryPoints = ["http"] backend = "dev_server" [frontends.api] entryPoints = ["http"] backend = "django" [frontends.api.routes.api] rule = "PathPrefix: /api/" [backends] [backends.dev_server] [backends.dev_server.servers] [backends.dev_server.servers.elmreactor] url = "http://localhost:8080" [backends.django] [backends.django.servers] [backends.django.servers.server1] url = "http://localhost:8000"
You will be able to connect to http://localhost:9000 all the ali calls to /api/ will go to localhost:8000 and all other request will go to localhost:8080 .
Start traefik with ./traefik -c traefik.toml
Access the proxy on http://localhost:9000
Update 1: 2018-02-26
Updated the number of solutions from 2 to 4. Thanks to Andraž Bajt - edific for recomending a simple add on and Marko Mrdjenovič - friedcell for adding the correct headers to the API itself (not the proxy). For more information see bellow.
If you have any questions or suggestions contact me on twitter @brodul :)