The same-origin policy and why CORS exists

The browser enforces a same-origin policy: JavaScript loaded from shop.example.com cannot, by default, read responses from api.personalization.com. It is protection against attacks in which a malicious site could read data from other sites on behalf of a signed-in user.

CORS is the mechanism that lets a server explicitly permit requests from named origins, exempting them from the same-origin policy.

How CORS works

A simple request (a GET with no custom headers):
1. The browser sends the request with the header Origin: https://shop.example.com.
2. The server checks whether that origin is allowed.
3. If it is, it returns Access-Control-Allow-Origin: https://shop.example.com.
4. The browser passes the response through to the JS.

Preflight for complex requests:

OPTIONS /api/recommendations HTTP/1.1
Origin: https://shop.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, X-API-Key

The server has to answer:

Access-Control-Allow-Origin: https://shop.example.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-API-Key
Access-Control-Max-Age: 86400

CORS during a personalization platform integration

When a JavaScript recommendation widget is connected, the browser calls the personalization API on a different domain. If the server does not return the right CORS headers:

  • The browser blocks the response — not the request; the server does receive it
  • The console shows CORS policy: No 'Access-Control-Allow-Origin' header
  • Recommendations never appear, although everything works server-side

Important: a CORS error is only visible in a browser. Test the API with curl or Postman and everything works, because those tools do not implement the same-origin policy. Check the integration in a real browser with DevTools open.

Common configuration mistakes

Mistake Symptom Fix
No CORS header Recommendations do not load Add Access-Control-Allow-Origin
Wildcard plus credentials Requests carrying cookies are blocked Name the origin and add Allow-Credentials: true
OPTIONS not handled Preflight returns 404 Add an OPTIONS handler to the router
The wrong domain A CORS error on a subdomain Allow *.shop.example.com, or each subdomain individually