Bird
Raised Fist0
Expressframework~10 mins

Preflight requests behavior in Express - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Preflight requests behavior
Browser sends OPTIONS request
↓
Server receives OPTIONS request
↓
Server checks CORS headers
↓
Browser sends actual request
↓
Server processes actual request
The browser first sends an OPTIONS request to check permissions. The server responds with CORS headers if allowed. Then the browser sends the real request.
Execution Sample
Express
app.options('/data', (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Methods', 'GET,POST');
  res.sendStatus(200);
});
This code handles the preflight OPTIONS request by sending CORS headers and a 200 OK status.
Execution Table
StepRequest TypeServer ActionResponse Headers SentBrowser Action
1OPTIONS (Preflight)Check if CORS allowed for origin and methodAccess-Control-Allow-Origin: *; Access-Control-Allow-Methods: GET,POSTIf allowed, proceed to send actual request
2GET (Actual request)Process GET request normallyAccess-Control-Allow-Origin: *Render or use response data
3POST (Actual request)Process POST request normallyAccess-Control-Allow-Origin: *Render or use response data
4OPTIONS (Preflight)If CORS not allowed, respond without CORS headersNo CORS headersBlock actual request, show error
5Actual requestBlocked by browser due to failed preflightNo responseRequest fails, error shown
💡 Execution stops when browser blocks actual request due to missing or invalid CORS headers in preflight response.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4After Step 5
Request TypeNoneOPTIONSGETPOSTOPTIONSActual request blocked
Server Response HeadersNoneCORS headers sentCORS headers sentCORS headers sentNo CORS headersNo response
Browser StateIdlePreflight sentActual request sentActual request sentPreflight failedRequest blocked
Key Moments - 3 Insights
Why does the browser send an OPTIONS request before the actual request?
The browser sends OPTIONS to check if the server allows the actual request's method and origin via CORS headers, as shown in execution_table step 1.
What happens if the server does not send CORS headers in response to the OPTIONS request?
The browser blocks the actual request because the preflight failed, as shown in execution_table steps 4 and 5.
Are CORS headers required on the actual GET or POST responses?
Yes, the server must send Access-Control-Allow-Origin on actual responses to allow the browser to accept them, as shown in execution_table steps 2 and 3.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what response headers does the server send during the OPTIONS preflight request when CORS is allowed?
AAccess-Control-Allow-Origin: *; Access-Control-Allow-Methods: GET,POST
BNo headers sent
CAccess-Control-Allow-Origin: none
DContent-Type: application/json
💡 Hint
Check execution_table row 1 under 'Response Headers Sent'
At which step does the browser block the actual request due to failed preflight?
AStep 2
BStep 5
CStep 3
DStep 1
💡 Hint
Look at execution_table rows 4 and 5 for blocked requests
If the server sends CORS headers only on the OPTIONS request but not on the actual GET request, what will happen?
ABrowser accepts the GET response normally
BBrowser retries the OPTIONS request
CBrowser blocks the GET response
DBrowser ignores CORS and proceeds
💡 Hint
Refer to key_moments about CORS headers on actual responses and execution_table steps 2 and 3
Concept Snapshot
Preflight requests are OPTIONS requests browsers send before actual requests to check CORS permissions.
Server must respond with Access-Control-Allow-Origin and Access-Control-Allow-Methods headers.
If allowed, browser sends actual request; otherwise, it blocks it.
CORS headers must be present on both preflight and actual responses.
This protects users by enforcing cross-origin security rules.
Full Transcript
When a browser wants to send a cross-origin request that is not simple, it first sends an OPTIONS request called a preflight. This preflight asks the server if the actual request is allowed by checking CORS headers. The server responds with headers like Access-Control-Allow-Origin and Access-Control-Allow-Methods if it permits the request. If the browser sees these headers, it proceeds to send the real request (GET, POST, etc.). If the server does not send these headers, the browser blocks the actual request to protect the user. The server must also send Access-Control-Allow-Origin on the actual response for the browser to accept it. This process ensures safe cross-origin communication.

Practice

(1/5)
1. What is the main purpose of a preflight request in Express when handling cross-origin requests?
easy
A. To check if the server allows the actual request method and headers before sending it
B. To send the actual data to the server immediately
C. To close the connection after the first request
D. To authenticate the user credentials

Solution

  1. Step 1: Understand preflight request role

    A preflight request uses the OPTIONS method to ask the server if the actual request is safe to send.
  2. Step 2: Identify what preflight checks

    It checks allowed methods and headers to prevent unauthorized cross-origin requests.
  3. Final Answer:

    To check if the server allows the actual request method and headers before sending it -> Option A
  4. Quick Check:

    Preflight checks permissions = B [OK]
Hint: Preflight = permission check before real request [OK]
Common Mistakes:
  • Thinking preflight sends actual data
  • Confusing preflight with authentication
  • Assuming preflight closes connection
2. Which Express method is used to handle preflight OPTIONS requests?
easy
A. app.options()
B. app.post()
C. app.get()
D. app.use()

Solution

  1. Step 1: Recall HTTP methods in Express

    Express provides methods matching HTTP verbs like get, post, options, etc.
  2. Step 2: Identify method for preflight

    Preflight requests use the OPTIONS method, so Express uses app.options() to handle them.
  3. Final Answer:

    app.options() -> Option A
  4. Quick Check:

    OPTIONS method handled by app.options() [OK]
Hint: Preflight uses OPTIONS, so use app.options() [OK]
Common Mistakes:
  • Using app.get() or app.post() for OPTIONS requests
  • Confusing app.use() as handler for OPTIONS
  • Not handling OPTIONS method at all
3. Consider this Express code snippet handling CORS preflight:
app.options('/data', (req, res) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET,POST');
  res.sendStatus(204);
});
What will the server respond to an OPTIONS request to '/data'?
medium
A. Status 404 Not Found
B. Status 204 with headers allowing any origin and GET, POST methods
C. Status 200 with no headers
D. Status 500 Internal Server Error

Solution

  1. Step 1: Analyze headers set in response

    The code sets 'Access-Control-Allow-Origin' to '*' allowing any origin, and 'Access-Control-Allow-Methods' to 'GET,POST'.
  2. Step 2: Check response status

    res.sendStatus(204) sends HTTP status 204 (No Content) with the headers.
  3. Final Answer:

    Status 204 with headers allowing any origin and GET, POST methods -> Option B
  4. Quick Check:

    Preflight responds 204 + CORS headers = C [OK]
Hint: 204 status with CORS headers means preflight success [OK]
Common Mistakes:
  • Expecting status 200 instead of 204
  • Missing CORS headers in response
  • Confusing 404 or 500 errors
4. You wrote this Express code to handle preflight requests:
app.options('/api', (req, res) => {
  res.header('Access-Control-Allow-Origin', 'https://example.com');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT');
  res.end();
});
But the browser still blocks the actual request. What is the likely problem?
medium
A. Access-Control-Allow-Origin should be '*'
B. Using res.end() instead of res.sendStatus(204)
C. Missing Access-Control-Allow-Headers header for custom headers
D. Incorrect URL path in app.options()

Solution

  1. Step 1: Understand preflight header requirements

    If the actual request uses custom headers, the server must respond with Access-Control-Allow-Headers listing them.
  2. Step 2: Check code for missing headers

    The code does not set Access-Control-Allow-Headers, so browser blocks the request due to missing allowed headers.
  3. Final Answer:

    Missing Access-Control-Allow-Headers header for custom headers -> Option C
  4. Quick Check:

    Missing allowed headers header blocks request = D [OK]
Hint: Always include Access-Control-Allow-Headers if custom headers used [OK]
Common Mistakes:
  • Assuming res.end() causes the block
  • Thinking Access-Control-Allow-Origin must be '*' always
  • Ignoring missing allowed headers header
5. You want to allow cross-origin requests only from 'https://trusted.com' with methods GET and POST, and allow custom header 'X-Custom-Auth'. Which Express preflight handler is correct?
hard
A. app.options('/resource', (req, res) => { res.header('Access-Control-Allow-Origin', 'https://trusted.com'); res.header('Access-Control-Allow-Headers', 'X-Custom-Auth'); res.sendStatus(404); });
B. app.options('/resource', (req, res) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT'); res.sendStatus(200); });
C. app.options('/resource', (req, res) => { res.header('Access-Control-Allow-Origin', 'https://trusted.com'); res.header('Access-Control-Allow-Methods', 'GET'); res.sendStatus(204); });
D. app.options('/resource', (req, res) => { res.header('Access-Control-Allow-Origin', 'https://trusted.com'); res.header('Access-Control-Allow-Methods', 'GET, POST'); res.header('Access-Control-Allow-Headers', 'X-Custom-Auth'); res.sendStatus(204); });

Solution

  1. Step 1: Match allowed origin and methods

    app.options('/resource', (req, res) => { res.header('Access-Control-Allow-Origin', 'https://trusted.com'); res.header('Access-Control-Allow-Methods', 'GET, POST'); res.header('Access-Control-Allow-Headers', 'X-Custom-Auth'); res.sendStatus(204); }); sets Access-Control-Allow-Origin to 'https://trusted.com' and methods to 'GET, POST' as required.
  2. Step 2: Include custom headers and correct status

    It includes Access-Control-Allow-Headers for 'X-Custom-Auth' and sends status 204 (No Content), which is correct for preflight.
  3. Final Answer:

    app.options('/resource', (req, res) => { res.header('Access-Control-Allow-Origin', 'https://trusted.com'); res.header('Access-Control-Allow-Methods', 'GET, POST'); res.header('Access-Control-Allow-Headers', 'X-Custom-Auth'); res.sendStatus(204); }); -> Option D
  4. Quick Check:

    Correct origin, methods, headers, and 204 status = A [OK]
Hint: Include origin, methods, headers, and send 204 for preflight [OK]
Common Mistakes:
  • Using '*' origin when only one domain allowed
  • Missing Access-Control-Allow-Headers for custom headers
  • Sending wrong status code like 200 or 404
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard