https://ieftimov.com/post/deep-dive-cors-history-how-it-works-best-practices/
Ilija Eftimov [?][?]
* Archive
* About
* Newsletter
* Suggest a topic
Deep dive in CORS: History, how it works, and best practices
Learn the history and evolution of same-origin policy and CORS,
understand CORS and the different types of cross-origin access in
depth, and learn (some) best practices.
April 12, 2021 * 20 min * Ilija
Table of Contents
* The error in your browser's console
* In the beginning was the first subresource
+ Origins & cross-origin
+ The many dangers of cross-origin requests
* Same-origin policy
* Enter CORS
+ Cross-origin writes
+ Preflight requests
+ Cross-origin reads
* Fine-tuning CORS
* Some best practices
+ Free for all
+ Keeping it in the family
+ NULL origins
+ Skip cookies, if you can
* Additional reading
The error in your browser's console#
No 'Access-Control-Allow-Origin' header is present on the
requested resource.
Cross-Origin Request Blocked: The Same Origin Policy disallows
reading the remote resource at https://example.com/
Access to fetch at 'https://example.com' from origin 'http://
localhost:3000' has been blocked by CORS policy.
I am sure you've seen one of these errors, or a variation, in your
browser's console. If you have not - don't fret, you soon will. There
are enough CORS errors for all developers out there.
These popping-up during development can be annoying. But in fact,
CORS is an incredibly useful mechanism in a world of misconfigured
web servers, hostile actors on the web and organizations pushing the
web standards ahead.
But let's go back the beginning…
In the beginning was the first subresource#
A subresource is an HTML element that is requested to be embedded
into the document, or executed in its context. In the year of 1993,
the first subresource
was introduced. By introducing
, the
web got prettier. And more complex.
Back to 1993 Back to 1993
You see, if your browser would render a page with an
on it, it
would actually have to go fetch that subresource from an origin. When
a browser fetches said subresource from an origin that does not
reside on the same scheme, fully qualified hostname or port - that's
a cross-origin request.
Origins & cross-origin#
An origin is identified by a triple: scheme, fully qualified hostname
and port. For example, http://example.com and https://example.com are
different origins - the first uses http scheme and the second https.
Also, the default http port is 80, while the https is 443. Therefore,
in this example, the two origins differ by scheme and port, although
the host is the same (example.com).
You get the idea - if any of the three items in the triple are
different, then the origin is different.
As an exercise if we run a comparison of the https://blog.example.com
/posts/foo.html origin against other origins, we would get the
following results:
URL Result Reason
https://blog.example.com/ Same Only the path differs
posts/bar.html
https://blog.example.com/ Same Only the path differs
contact.html
http://blog.example.com/ Different Different protocol
posts/bar.html
https:// Different port (https:// is
blog.example.com:8080/posts/ Different port 443 by default)
bar.html
https://example.com/posts/ Different Different host
bar.html
A cross-origin request means, for example, a resource (i.e. page)
such as http://example.com/posts/bar.html that would try to render a
subresource from the https://example.com origin (note the scheme
change!).
The many dangers of cross-origin requests#
Now that we defined what same- and cross-origin is, let's see what is
the big deal.
When we introduced
to the web, we opened the floodgates. Soon
after the web got