Enabling CORS on your dev server

hostlocal routes your viewer’s requests through a different browser origin. Your local server must send the Access-Control-Allow-Origin header, or the browser will silently block the response. Pick your stack below.

Node.js — Express

Install the cors middleware, then call it before your routes.

Install
npm install cors
app.js — diff
 const express = require('express');
+const cors    = require('cors');
 
 const app = express();
+app.use(cors());
 
 app.get('/', (req, res) => res.send('Hello world'));
 app.listen(3000);

cors() with no arguments allows all origins — fine for local dev. See the cors docs for fine-grained options.

Node.js — Fastify

Register @fastify/cors as a plugin.

Install
npm install @fastify/cors
server.js — diff
 const fastify = require('fastify')({ logger: true });
+await fastify.register(require('@fastify/cors'), { origin: true });
 
 fastify.get('/', async () => 'Hello world');
 await fastify.listen({ port: 3000 });
Vite dev server

One option in vite.config.js (or .ts).

vite.config.js — diff
 export default {
   server: {
+    cors: true,
   },
 };

Restart Vite after saving the config.

Webpack Dev Server
webpack.config.js — diff
 module.exports = {
   devServer: {
+    headers: {
+      'Access-Control-Allow-Origin': '*',
+    },
   },
 };
Python — Flask

Use flask-cors to add the header to all responses.

Install
pip install flask-cors
app.py — diff
 from flask import Flask
+from flask_cors import CORS
 
 app = Flask(__name__)
+CORS(app)
 
 @app.route('/')
 def index():
     return 'Hello world'
 
 if __name__ == '__main__':
     app.run(port=5000)

Or run with the CLI — no code change needed if CORS(app) is already in place:

flask run --port 5000
Python — Django

Use django-cors-headers.

Install
pip install django-cors-headers
settings.py — diff
 INSTALLED_APPS = [
+    'corsheaders',
     'django.contrib.contenttypes',
     # …
 ]
 
 MIDDLEWARE = [
+    'corsheaders.middleware.CorsMiddleware',
     'django.middleware.common.CommonMiddleware',
     # …
 ]
 
+CORS_ALLOW_ALL_ORIGINS = True

CorsMiddleware must appear before CommonMiddleware.

Ruby on Rails

Rails ships with rack-cors already in the Gemfile (commented out). Uncomment it.

Gemfile — diff
-# gem "rack-cors"
+gem "rack-cors"
Install
bundle install
config/initializers/cors.rb — diff
 Rails.application.config.middleware.insert_before 0, Rack::Cors do
+  allow do
+    origins '*'
+    resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head]
+  end
 end

Restart rails server after adding the initializer.

PHP — Laravel

Laravel includes a CORS config file out of the box. Just edit it.

config/cors.php — diff
 return [
     'paths' => ['api/*', 'sanctum/csrf-cookie'],
-    'allowed_origins' => ['https://yourfrontend.example'],
+    'allowed_origins' => ['*'],
     'allowed_methods' => ['*'],
     'allowed_headers' => ['*'],
     'exposed_headers' => [],
     'max_age' => 0,
     'supports_credentials' => false,
 ];

The HandleCors middleware is already registered globally in Laravel 9+. No additional setup needed.

ASP.NET Core
Program.cs — diff
 var builder = WebApplication.CreateBuilder(args);
+builder.Services.AddCors(options =>
+    options.AddDefaultPolicy(policy =>
+        policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
 
 var app = builder.Build();
+app.UseCors();
 
 app.MapGet("/", () => "Hello world");
 app.Run();
Go — net/http

Add a simple middleware wrapper — no external packages needed.

main.go — diff
 package main
 
 import (
 	"fmt"
 	"net/http"
 )
 
+func withCORS(h http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("Access-Control-Allow-Origin", "*")
+		w.Header().Set("Access-Control-Allow-Headers", "*")
+		if r.Method == http.MethodOptions { return }
+		h.ServeHTTP(w, r)
+	})
+}
+
 func main() {
 	mux := http.NewServeMux()
 	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 		fmt.Fprintln(w, "Hello world")
 	})
-	http.ListenAndServe(":3000", mux)
+	http.ListenAndServe(":3000", withCORS(mux))
 }

If you use Gin, use github.com/gin-contrib/cors instead.

Other servers / manual header

If your server is not listed above, the raw header to add to every response is:

Access-Control-Allow-Origin: *

For servers that serve static files, many support a custom header config file. For example, Caddy:

localhost:3000 {
  header Access-Control-Allow-Origin *
  file_server
}

Or nginx (in a location block):

add_header Access-Control-Allow-Origin *;

Or Python’s built-in http.server (no CORS support — use a wrapper):

pip install cors-python
python -m cors_python 3000

Not sure which header is missing? Open DevTools → Network, find the blocked request, and check the Response Headers tab. The browser console will also name the exact header that is absent.