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
OPTIONSrequest 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:
- The server allows requests from
http://localhost:3000(origin) - The server allows PUT methods
- The server accepts the
Authorizationheader
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:
