CORS explained the big picture

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the web-development category.

Last Updated: 2024-04-19

"Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own." Source

CORS is implemented in newer browsers (not older). E.g. You'll bump into it when calling fetch or making an XMLHttpRequest request.

CORS is used for:

CORS has two modes:

  1. GET requests - adds new HTTP headers that let servers describe which origins are permitted to read that information from a web browser.

e.g. A pages served on http://www.example.com attempts a cross-origin request to fetch the user's data from http://service.example.com. An Origin http://www.example.com header is added. The service at service.example.com uses an Access-Control-Allow-Origin header to specify that example.com is allowed (or a wildcard * for all origins).

  1. POST (and other side-effect causing requests)

"The specification mandates that browsers "preflight" the request, soliciting supported methods from the server with the HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request. Servers can also inform clients whether "credentials" (such as Cookies and HTTP Authentication) should be sent with requests." - source

Most common error situation encountered

Your JavaScript code makes a request to another server and fails.

Localhost

Localhost and 127.0.0.1 are different domains so localhost dev may fail if you mix these up.

localhost might have CORS disabled in Chrome, so may not be a good tset.

How to test a CORS setup is working

curl --header "Content-Type: application/json" \
  -H "Access-Control-Request-Method: GET" \
  -H "Origin: http://example.com"
  --verbose \
  --data '{"country_code":"DE","account_number":"0532013000", "bank_code":"3704"}' \

You should see Access-Control-Allow-Origin header in the response if it works.