Handling Preflight (OPTIONS) Requests & Methods

Introduction

Welcome back! In our previous lesson, we explored the basics of Cross-Origin Resource Sharing (CORS) and its significance in web development. Now, we're going to dive deeper into a crucial aspect of CORS: preflight requests. These requests play a vital role in ensuring secure cross-origin communication. Think of them as a security check before allowing access to resources. By the end of this lesson, you'll understand what preflight requests are, when they occur, and how to handle them effectively in your TypeScript REST API. Let's get started! 🚀

Understanding Preflight Requests

Preflight requests are a part of the CORS mechanism that browsers use to determine if a cross-origin request is safe to send. They are triggered when a request uses methods other than simple methods like GET, HEAD, or POST (with certain content types), or when custom headers are included. To be more specific, POST requests are only considered "simple" if they use one of the following content types: application/x-www-form-urlencoded, multipart/form-data, or text/plain. If a POST request uses application/json—which is common in modern APIs—it will trigger a preflight request. This is an important detail that explains why many seemingly normal API requests may involve a preflight check.

Here's how preflight requests work:

  • When you make a "non-simple" cross-origin request, the browser first sends an OPTIONS request to the server
  • This preflight request checks if the actual request is allowed based on origin, method, and headers
  • The server responds with specific CORS headers indicating what's permitted
  • Only if the preflight is successful will the browser send the actual request

Imagine you're entering a secure building; a preflight request is like the security guard checking your credentials before letting you in. Without proper handling of these preflight requests, certain cross-origin requests will be blocked by browsers.

Why Preflight Requests Matter

To understand why we need to handle preflight requests properly, let's look at a common scenario:

Suppose your frontend (running on http://localhost:3000) needs to make a PUT request to your API (running on http://localhost:8000) with a custom Authorization header. Before sending the actual PUT request, the browser will automatically send an OPTIONS request to check if:

  1. The server allows requests from http://localhost:3000 (origin)
  2. The server allows PUT methods
  3. The server accepts the Authorization header

If your server doesn't properly respond to this OPTIONS request with the appropriate CORS headers, the browser will block the actual PUT request, and you'll see an error like:

Access to fetch at 'http://localhost:8000/api/resource' from origin 'http://localhost:3000' 
has been blocked by CORS policy: Response to preflight request doesn't pass 
access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal