CORS Preflight OPTIONS Requests in JavaScript

This article explains what Cross-Origin Resource Sharing (CORS) preflight OPTIONS requests are, why modern web browsers automatically trigger them during JavaScript fetch operations, the conditions that cause them, and how back-end servers must respond to handle them properly.

What Is a CORS Preflight Request?

A CORS preflight request is an automated HTTP OPTIONS request sent by a web browser to a target server before executing the actual network request. It acts as a safety check to determine whether the destination server understands the CORS protocol and grants permission for the client’s origin domain to perform the requested operation with specific methods and headers.

If the server grants permission by returning appropriate CORS response headers with a successful HTTP status code (typically 200 OK or 204 No Content), the browser proceeds with the original fetch call. If the server fails to respond or omits the necessary CORS headers, the browser blocks the main request and throws a CORS network error in the JavaScript console.

Why Browsers Send Preflight Requests

Before CORS was standardized, cross-origin requests were heavily restricted to simple forms and image tags to prevent malicious websites from executing unauthorized operations against protected servers.

When modern JavaScript APIs like fetch and XMLHttpRequest enabled sending arbitrary HTTP methods (such as DELETE or PATCH) and custom headers (such as Authorization), browsers needed a mechanism to prevent potential side effects on legacy servers not designed to handle these requests. The preflight check ensures the server explicitly consents to the operation before any modifying payload reaches the server’s endpoint logic.

Conditions That Trigger a Preflight Request

A browser automatically initiates a preflight OPTIONS request if the fetch call does not qualify as a “simple request.” A request requires a preflight check if it meets any of the following conditions:

The Preflight Request and Response Headers

During the preflight phase, the browser automatically attaches specific metadata headers to the OPTIONS request:

To successfully fulfill the preflight check, the server must respond with matching authorization headers:

Optimizing Preflight Performance

Because preflight requests introduce an additional network round-trip that increases latency, applications can optimize them using the following techniques:

  1. Leverage the Access-Control-Max-Age Header: Configure the server to return an Access-Control-Max-Age header (e.g., 86400 for 24 hours). The browser will cache the permission and skip preflight checks for identical requests during that window.
  2. Use Simple Requests Where Feasible: When low latency is critical and advanced security headers or JSON bodies are not strictly necessary, structuring payloads to use standard form encodings allows requests to bypass the preflight phase entirely.