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