Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
HTTP in Depth  ›  Capstone Project

CORS — Cross-Origin Requests

CORS 15 minBrowsers block pages from reading responses from another origin unless the server's CORS headers grant that origin, method and headers, sometimes after an OPTIONS preflight.

CORS — Cross-Origin Requests

BookNook's website lives at https://booknook.example, and its API at https://api.booknook.example. The first time the website's JavaScript calls the API, the browser console fills with red: "blocked by CORS policy". The API is working. The browser is protecting users, and your API has to tell it this caller is welcome.

The rule

The browser asks; the server's headers grant; nobody else enforces it.

An origin is the combination of scheme, host and port. https://booknook.example and https://api.booknook.example differ in host, so they are different origins. By default, browsers stop page JavaScript from reading responses from another origin. This same-origin policy keeps a malicious site from reading your bank data with your cookies.

CORS (Cross-Origin Resource Sharing) is how a server relaxes that rule for chosen origins. The browser adds an Origin header; the server answers with permission headers:

GET /v1/books HTTP/1.1
Origin: https://booknook.example

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://booknook.example

For anything beyond a basic request (a method other than GET, HEAD or POST, a body type such as application/json, or extra headers like Authorization), the browser first sends a preflight, an automatic OPTIONS request that asks permission:

OPTIONS /v1/loans/901 HTTP/1.1
Origin: https://booknook.example
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: authorization

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://booknook.example
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE
Access-Control-Allow-Headers: authorization, content-type
Access-Control-Max-Age: 600

Only if the preflight grants permission does the browser send the real DELETE. Access-Control-Max-Age lets it remember the answer for 10 minutes.

To send cookies across origins, the server must also reply Access-Control-Allow-Credentials: true, and then Access-Control-Allow-Origin must name the exact origin; the wildcard * is not accepted.

The shortcut

Diagnose a CORS error in three checks: Is it a browser? Are the origins different? Do the response headers grant this origin, method and headers?

The website's "return book" button failsStep 1 of 3
  1. Is it a browser?

    Yes, page JavaScript. The same call from a server or curl would work, because CORS is only enforced by browsers.

The trap is thinking CORS protects your API. It does not stop curl or a server calling you; it only stops other websites' pages from reading responses in a user's browser. Your API still needs real authentication.

Drills

Answer fast — trust the rule.

quick drill

Which pair has the SAME origin?

quick drill

Who enforces CORS?

quick drill

The website sends a PATCH with Content-Type: application/json. What does the browser do first?

quick drill

The API replies Access-Control-Allow-Origin: * and the site sends cookies with its requests. What happens?

quick drill

A teammate says "we set strict CORS, so attackers cannot call our API". What is wrong?

Remember

  • The browser asks; the server's headers grant; nobody else enforces it.
  • Shortcut: is it a browser, are the origins different, do the headers grant it?
  • Trap: treating CORS as security for your API, and * with credentials.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainFix a CORS failure

The BookNook website at https://booknook.example gets a CORS error when its JavaScript sends DELETE to https://api.booknook.example/v1/loans/901 with an Authorization header. Explain why the browser is involved, what request it sends first, and which response headers the API must return.