Frontend Interview Questions

CORS Explained: Same-Origin Policy and Preflight Requests

"Explain CORS. When does a preflight request happen, and what headers are involved?"

Why Interviewers Ask This

CORS is asked in almost every frontend interview because it's the #1 thing junior developers get stuck on. Interviewers want to see you understand why the policy exists (security), when preflights fire (specific request shapes), and how to configure servers correctly.

How to Answer

  1. 1

    Start with the Same-Origin Policy: a script on https://a.com can only read responses from https://a.com. Origin = protocol + domain + port. The goal is to stop a malicious site from reading your logged-in bank data via a script on its page.

  2. 2

    CORS is the controlled exception: the server can opt-in to allow specific cross-origin requests via Access-Control-Allow-Origin and friends.

  3. 3

    Simple requests: GET, HEAD, or POST with only safe content-types (application/x-www-form-urlencoded, multipart/form-data, text/plain) and no custom headers. Browser sends the request directly with an Origin header; server responds with Access-Control-Allow-Origin. If it doesn't match, the browser blocks the response from JS (the server still received the request).

  4. 4

    Preflight requests: any request using PUT/DELETE/PATCH, or any request with a JSON content type, or any request with custom headers like Authorization triggers an OPTIONS preflight first. The OPTIONS includes Access-Control-Request-Method and Access-Control-Request-Headers; the server responds with Access-Control-Allow-Methods and Access-Control-Allow-Headers. If approved, the actual request fires. Preflights can be cached per Access-Control-Max-Age.

  5. 5

    Credentials: to send cookies cross-origin, client must set fetch credentials: "include" AND server must respond Access-Control-Allow-Credentials: true AND Access-Control-Allow-Origin cannot be "*" — it must be the exact origin.

Sample Answer

CORS — Cross-Origin Resource Sharing — is how browsers let scripts make cross-origin requests safely. The baseline Same-Origin Policy blocks script from reading a response if the response's origin (scheme + host + port) doesn't match the requesting page's origin. This exists so malicious code on evil.com can't run fetch("https://bank.com/api/balance") and read your logged-in bank account. CORS relaxes this when the target server opts in via specific response headers. There are two flavors of cross-origin requests. Simple requests are GET/HEAD or POST with content-type in a safe list (application/x-www-form-urlencoded, multipart/form-data, text/plain) and no custom headers like Authorization. The browser sends the actual request directly with an Origin header. The server can respond with Access-Control-Allow-Origin: https://a.com (or *). If the header matches, JS can read the response; if not, the browser blocks it — though note the request did reach the server. Preflighted requests are anything else: PUT, DELETE, PATCH; or Content-Type: application/json; or custom headers like Authorization. The browser first sends an OPTIONS request with Access-Control-Request-Method: PUT and Access-Control-Request-Headers: Authorization, Content-Type. The server must respond with Access-Control-Allow-Methods: PUT, POST, Access-Control-Allow-Headers: Authorization, Content-Type, and Access-Control-Allow-Origin. If these match what the preflight asked for, the real request fires. Otherwise the browser aborts. Preflights can be cached for Access-Control-Max-Age seconds so subsequent identical requests skip them. Credentials — cookies, HTTP Basic auth, TLS client certs — are not sent cross-origin by default. To include them: client must set fetch's credentials: "include" (or XHR's withCredentials = true), AND the server must respond with Access-Control-Allow-Credentials: true, AND Access-Control-Allow-Origin must be the specific origin — wildcard * is rejected for credentialed requests. This trio is the source of the most common CORS bug in production. Also note: CORS is enforced by the browser; a server making the same cross-origin HTTP call from Node has no CORS concerns because no browser is involved.

Pro Tips

  • Always explain why CORS exists before how it works — the security motivation often matters in interviews.

  • Memorize the three conditions for simple vs preflight — it comes up constantly.

  • The credentials + wildcard gotcha is interview gold — saying "Access-Control-Allow-Origin cannot be * with credentials" instantly signals experience.

  • If you blank on header names during a live interview, HireMe AI can surface Access-Control-Allow-Origin / Methods / Headers on demand.

Frequently Asked Questions

Does CORS prevent CSRF?

No, they're different. CORS controls what scripts can read; CSRF is about unintended actions via a victim's browser. You still need CSRF tokens or SameSite cookies.

Why does the server still receive a preflight-failed request?

The browser sends the OPTIONS, the server responds, and the browser decides whether to proceed. The real request is blocked on the client side. For state-changing requests, always put CSRF protection server-side too.

What's the difference between CORS and a reverse proxy?

A reverse proxy makes requests same-origin by routing through your own domain. CORS is the browser-coordinated opt-in. Proxies are simpler for frontend devs; CORS is necessary when the API is genuinely on a different domain.

Worried About Going Blank in Your Interview?

HireMe AI listens to your interview in real-time, detects questions, and generates instant answer suggestions — so you never freeze up again.

Try HireMe AI Free