logoPushwant Rai
Home
Experience
Education
Projects
Achievements
Blogs

Elsewhere

GitHub
LinkedIn
hi@pushwantrai.com.np

Theme

Understanding CORS: Part 1 - The Basics

Aug 04, 2023

#CORS#Web Development#Cross-Origin Requests#Frontend

Table of Contents

  • Introduction
  • The CORS Flow
  • Understanding CORS Headers
  • CORS in Action
  • Working with Express
  • Managing Origins

Introduction

You've set up your server, tested it with a REST client like Postman, and everything is running smoothly. Confidently, you integrate it with your web application, expecting everything to work like magic. But then, out of nowhere, you're hit with a curveball - a dreaded CORS error.

CORS Error Example

So, what is CORS? Let's start with what the official MDN Web Docs says about CORS

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources.

In simpler terms, CORS is a security mechanism built into browsers that requires specific HTTP headers to be exchanged between browsers and servers before allowing cross-origin requests.

CORS Flow Diagram

The CORS Flow

Here's exactly what happens when a CORS request is made:

  1. Your browser sends an HTTP OPTIONS preflight request to the server
  2. The server responds with CORS headers
  3. The browser permits or deny the response
  4. If successful, the browser proceeds with the cross-origin request
  5. If not permitted, it's blocked due to a CORS policy error

Understanding CORS Headers

When a cross-origin request is made, browsers and servers exchange several important headers:

Key CORS Headers

  1. Access-Control-Allow-Origin

    • Specifies which origins can access the resource
    • Can be * (all origins) or specific domains
    • MDN Documentation
  2. Access-Control-Allow-Methods

    • Lists allowed HTTP methods (GET, POST, PUT, etc.)
    • Part of the preflight response
    • MDN Documentation
  3. Access-Control-Allow-Headers

    • Defines permitted HTTP headers
    • Responds to preflight requests
    • MDN Documentation
  4. Access-Control-Allow-Credentials

    • Controls inclusion of credentials in requests
    • Essential for cookie-based authentication
    • MDN Documentation

CORS in Action

Let's see how CORS works with a simple Express server:

// Basic Express server setup const express = require("express"); const app = express(); const port = 3000; app.use(express.json()); app.get("/products", (req, res) => { if (!products || products.length === 0) { return res.status(404).json({ error: "Products not found" }); } res.json(products); }); app.listen(port, () => { console.log(`Server running at http://localhost:${port}`); });

When we make a basic fetch request:

fetch(`http://localhost:3004/products`, {}) .then((response) => console.log(response.json()))

We encounter our first CORS error:

CORS Error

Working with Express

To handle CORS properly in Express, we can use the cors middleware:

const cors = require('cors'); app.use(cors());

This enables CORS with default settings, allowing requests from any origin:

Successful CORS Response

Managing Origins

For better security, you can restrict allowed origins:

const allowedOrigins = ["http://localhost:3000", "https://example.com"] app.use(cors({ origin: function (origin, callback) { if(allowedOrigins.indexOf(origin) !== -1){ callback(null, origin) } else { callback(null, null); } } }));

What's Next?

In Part 2, we'll dive deeper into:

  • Different fetch modes and their behaviors
  • Advanced CORS configurations
  • Best practices for production environments

Related Resources

  • MDN CORS Documentation
  • Fetch API Specification
  • Express CORS Middleware

[Continue to Part 2: Understanding Fetch API Modes...]