DEV Community

Russell Jones
Russell Jones

Posted on • Originally published at jonesrussell.github.io on

CORS: Fix Cross-Origin Issues

Ahnii!

CORS (Cross-Origin Resource Sharing) lets your API accept requests from different domains. Without it, browsers block cross-origin requests for security.

CORS Diagram

The Problem

Browsers enforce same-origin policy. Different protocol, host, or port = different origin = blocked request.

Examples of different origins:

  • http://localhost:3000 and http://localhost:8080 (different ports)
  • https://api.example.com and http://api.example.com (different protocols)

Quick Fix

Add this function to your handler:

func enableCORS(w *http.ResponseWriter) {
    (*w).Header().Set("Access-Control-Allow-Origin", "*")
}

Enter fullscreen mode Exit fullscreen mode

Call it in your handler:

func handleAPI(w http.ResponseWriter, r *http.Request) {
    enableCORS(&w)

    // Your API logic here
    json.NewEncoder(w).Encode(data)
}

Enter fullscreen mode Exit fullscreen mode

Secure Implementation

Don’t use * in production. Specify allowed origins:

func enableCORS(w *http.ResponseWriter) {
    (*w).Header().Set("Access-Control-Allow-Origin", "https://yourdomain.com")
    (*w).Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
    (*w).Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
}

Enter fullscreen mode Exit fullscreen mode

Handle Preflight Requests

For non-simple requests (POST with custom headers, PUT, DELETE), browsers send OPTIONS requests first:

func handleAPI(w http.ResponseWriter, r *http.Request) {
    enableCORS(&w)

    if r.Method == "OPTIONS" {
        w.WriteHeader(http.StatusOK)
        return
    }

    // Your API logic
}

Enter fullscreen mode Exit fullscreen mode

Production Setup

Use a dedicated CORS middleware like rs/cors:

import "github.com/rs/cors"

c := cors.New(cors.Options{
    AllowedOrigins: []string{"https://yourdomain.com"},
    AllowedMethods: []string{"GET", "POST", "PUT", "DELETE"},
    AllowedHeaders: []string{"Content-Type", "Authorization"},
})

handler := c.Handler(http.HandlerFunc(yourHandler))

Enter fullscreen mode Exit fullscreen mode

Final Thoughts

CORS is a server-side solution. Set the headers on your API, not your frontend. Always be specific with your allowed origins in production, and consider using a battle-tested middleware like rs/cors for complex setups.

Got questions about CORS implementation? Drop a comment below!

Baamaapii 👋

Top comments (0)