Preflight Request

May 20, 2023

In the context of web development, a preflight request refers to a preliminary request made by a web browser, known as the “preflight request,” before making a cross-origin request for a resource on a web server. The purpose of the preflight request is to determine whether the server supports the particular HTTP method, headers, and other parameters that the intended cross-origin request will utilize. This process is necessary due to security concerns related to cross-origin requests.

Cross-Origin Requests

In web development, a cross-origin request occurs when a web page hosted on one domain (origin) sends a request to a web server hosted on a different domain (origin). Cross-origin requests are usually initiated by JavaScript code running on the web page, and they can be of different types, such as GET, POST, PUT, DELETE, etc.

Cross-origin requests are subject to the same-origin policy, a security feature implemented by web browsers that restricts web pages from accessing resources hosted on different domains. The same-origin policy prevents web pages from making malicious requests to other domains on behalf of the user, thereby protecting the user’s data and privacy. However, there are legitimate use cases where cross-origin requests are needed, such as accessing resources from a third-party API service.

CORS

Cross-Origin Resource Sharing (CORS) is a mechanism that allows web pages to make authorized cross-origin requests to web servers. CORS is implemented by adding specific HTTP headers to the server’s response to indicate which origins are allowed to access the server’s resources, which methods are allowed, and which headers are allowed. By default, a web server only allows requests from the same origin, but CORS enables the server to specify which other origins are allowed, and under what conditions.

CORS works by adding two types of headers to the HTTP request and response:

Request Headers

  • Origin: The origin of the web page making the request.
  • Access-Control-Request-Method: The HTTP method (e.g., GET, POST, etc.) that will be used in the actual cross-origin request.
  • Access-Control-Request-Headers: A list of headers that the web page wants to include in the actual cross-origin request.

Response Headers

  • Access-Control-Allow-Origin: Specifies which origin(s) are allowed to access the server’s resources. This header can have one of the following values:
    • An asterisk (*), which allows any origin to access the resource.
    • The exact origin that made the request, which allows only that origin to access the resource.
    • A list of origins, separated by commas, which allows those origins to access the resource.
  • Access-Control-Allow-Methods: Specifies which HTTP methods are allowed for the cross-origin request.
  • Access-Control-Allow-Headers: Specifies which headers are allowed for the cross-origin request.
  • Access-Control-Max-Age: Specifies the maximum time (in seconds) that the browser can cache the preflight response.

Preflight Request Process

Before making a cross-origin request, the browser first sends a preflight request to the server to check whether the actual cross-origin request is allowed. The preflight request is an HTTP OPTIONS request that includes the following headers:

  • Origin: The origin of the web page making the request.
  • Access-Control-Request-Method: The HTTP method (e.g., GET, POST, etc.) that will be used in the actual cross-origin request.
  • Access-Control-Request-Headers: A list of headers that the web page wants to include in the actual cross-origin request.

The server must respond to the preflight request with the following headers:

  • Access-Control-Allow-Origin: Specifies which origin(s) are allowed to access the server’s resources. This header can have one of the following values:
    • An asterisk (*), which allows any origin to access the resource.
    • The exact origin that made the request, which allows only that origin to access the resource.
    • A list of origins, separated by commas, which allows those origins to access the resource.
  • Access-Control-Allow-Methods: Specifies which HTTP methods are allowed for the cross-origin request.
  • Access-Control-Allow-Headers: Specifies which headers are allowed for the cross-origin request.
  • Access-Control-Max-Age: Specifies the maximum time (in seconds) that the browser can cache the preflight response.

If the server does not respond with these headers, or if the headers do not match the requirements of the cross-origin request, then the browser will not make the actual cross-origin request, and will instead return an error to the JavaScript code.

Why Use a Preflight Request?

The preflight request process is necessary because cross-origin requests have security implications. For example, an attacker could use JavaScript code on a malicious website to send a cross-origin request to a web server, with the intention of stealing data or performing unauthorized actions. To prevent such attacks, web servers must implement CORS, which allows them to specify which origins are allowed to access their resources, and under what conditions.

The preflight request process ensures that the actual cross-origin request will not violate the server’s CORS policies. By checking the server’s response to the preflight request, the browser can determine whether the actual cross-origin request is allowed, and if so, with which parameters.