Why Does a POST Request Appear Twice? Unraveling CORS Preflight Mechanics

POST requests can be sent twice in cross‑origin scenarios because browsers issue a CORS preflight OPTIONS request first, and only after the server approves the request does the actual POST occur; understanding same‑origin policy, simple vs complex requests, and proper server header configuration prevents this duplication.

Cognitive Technology Team
Cognitive Technology Team
Cognitive Technology Team
Why Does a POST Request Appear Twice? Unraveling CORS Preflight Mechanics

In web development, cross‑origin requests often trigger a CORS preflight mechanism, which can cause a POST request to be sent twice.

1. Background: Same‑Origin Policy Restrictions

The browser enforces the Same‑Origin Policy, allowing a page to access resources only when the protocol, domain, and port are identical. Examples: https://example.com:8080 vs http://example.com (different protocol). https://example.com vs https://api.example.com (different domain). https://example.com:80 vs https://example.com:443 (different port).

If a page tries to access a different origin, the browser blocks the request unless the server explicitly permits it.

2. CORS Specification and the Birth of Preflight Requests

The W3C introduced the CORS (Cross‑Origin Resource Sharing) specification, which lets the server decide whether to allow cross‑origin requests. The process distinguishes between simple and complex requests.

Simple Request : Uses methods GET, POST, or HEAD, includes only safe headers (Accept, Accept‑Language, Content‑Type with values application/x-www-form-urlencoded, multipart/form-data, or text/plain), and has a plain‑text body without sensitive data. No preflight is triggered.

Complex Request : Uses other methods (e.g., PUT), custom headers, or a JSON body. The browser first sends an OPTIONS preflight request to ask the server whether the cross‑origin request is allowed.

3. Why a POST Request Is Sent Twice: Preflight Triggered

When a cross‑origin request triggers the preflight mechanism, the POST request is effectively sent twice:

First: OPTIONS preflight request – The browser asks the server for permission, expecting CORS response headers such as Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, and Access-Control-Max-Age. If the server does not respond correctly, the browser aborts the subsequent request.

Second: Actual POST request – If the preflight succeeds, the browser sends the real POST request with the user’s data (form fields, JSON, etc.).

Example scenario : A frontend hosted at https://frontend.com sends a JSON POST to a backend API at https://api.example.com. The browser first issues an OPTIONS request; upon a successful response, it proceeds with the POST.

4. Design Purpose of Preflight Requests

The preflight request aims to protect users by preventing malicious sites from abusing cross‑origin requests. It helps defend against CSRF attacks by requiring the server to validate the Origin header and can block high‑risk operations (e.g., DELETE, PUT) unless explicitly allowed.

5. How to Resolve the Double POST Issue

Configure CORS headers on the server – Respond correctly to OPTIONS requests. Example Node.js middleware:

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', 'https://frontend.com');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  if (req.method === 'OPTIONS') return res.status(200).end();
  next();
});

Frontend optimizations – Prevent duplicate form submissions, use proxy servers during development, or simplify requests to qualify as simple requests.

Alternative techniques – For legacy systems that do not support CORS, use JSONP (GET only) or WebSocket communication.

6. Summary

The phenomenon of a POST request being sent twice is fundamentally the browser’s preflight mechanism enforcing CORS security. Developers must understand the CORS spec, configure appropriate server response headers, and optimize request logic to satisfy functional requirements while maintaining security and stability.

securityWeb developmentCORSCross-OriginPOSTpreflight
Cognitive Technology Team
Written by

Cognitive Technology Team

Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.