logoPushwant Rai
Home
Experience
Education
Projects
Achievements
Blogs

Elsewhere

GitHub
LinkedIn
hi@pushwantrai.com.np

Theme

Understanding CORS: Part 2 - Fetch API Modes and CORS Configurations

Aug 17, 2023

#CORS#Web Development#Fetch API#Frontend#JavaScript

Table of Contents

  • Introduction
  • Fetch API Modes Overview
  • Same-Origin Mode
  • CORS Mode
  • No-CORS Mode
  • CORS Configurations
  • Best Practices

Introduction

In Part 1, we explored the fundamentals of CORS and its basic implementation. Now, let's dive deeper into the different modes available in the Fetch API and how they interact with CORS policies.

Fetch API Modes Overview

The Fetch API provides several modes that control how cross-origin requests are handled:

  • same-origin (default)
  • cors
  • no-cors
  • navigate

Each mode serves a specific purpose and comes with its own set of rules and limitations.

Same-Origin Mode

The default mode in Fetch API is same-origin. As we discovered in Part 1, this is the most restrictive mode.

// Default same-origin mode fetch('http://localhost:3004/products')

Remember: A request is considered cross-origin if any of these differ:

  • Protocol (http/https)
  • Domain
  • Port number

Even a different port on the same domain triggers a CORS error:

Same Origin Error

CORS Mode

When working with cross-origin requests, cors mode is your primary tool:

fetch('http://localhost:3004/products', { mode: 'cors' })

This mode enables:

  1. Sending the Origin header
  2. Reading the response if proper CORS headers are present
  3. Supporting preflight requests when necessary

With proper server configuration:

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

The request succeeds with proper CORS headers:

Successful CORS

No-CORS Mode

The often misunderstood no-cors mode:

fetch('http://localhost:4000/customers', { mode: 'no-cors' })

While this mode appears to work (no CORS errors), it comes with significant limitations:

No-CORS Response

Key limitations:

  1. Response type is "opaque"
  2. Response body is null
  3. Cannot access response data in your code
  4. Status code is always 0

Use cases for no-cors:

  • Caching responses
  • Loading images or resources
  • Analytics requests
  • Cases where response data isn't needed

CORS Configurations

Managing Origins

For production applications, you'll want to 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); } } }));

Handling Credentials

When working with authenticated requests:

// Client-side fetch('http://api.example.com/data', { mode: 'cors', credentials: 'include' }) // Server-side app.use(cors({ credentials: true, origin: 'http://localhost:3000' }));

Best Practices

  1. Mode Selection

    • Use cors mode for cross-origin requests
    • Stick with default same-origin for same-origin requests
    • Only use no-cors when response data isn't needed
  2. Security

    • Never use * for Access-Control-Allow-Origin in production
    • Maintain a whitelist of allowed origins
    • Be specific with allowed methods and headers
  3. Error Handling

    fetch('http://api.example.com/data', { mode: 'cors' }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .catch(error => { console.error('CORS or network error:', error); });
  4. Development vs Production

    • Use permissive CORS settings in development
    • Implement strict origin checks in production
    • Monitor CORS errors in production logs

What's Next?

In the next part of this series, we'll explore:

  • Understanding Access-Control-Allow-Methods
  • Working with Access-Control-Allow-Headers
  • Managing credentials with Access-Control-Allow-Credentials

Until then, remember that CORS is not just a hurdle to overcome but a crucial security feature that protects users when implemented correctly.

Related Resources

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

[Continue to Part 3: CORS: Headers, Methods, and Credentials...]