CORS Explained
Cross-Origin Resource Sharing (CORS) is a security mechanism implemented by web browsers that controls access to resources from different origins. An origin is defined by the combination of protocol (e.g., HTTP, HTTPS), domain (e.g., example.com), and port (e.g., 80, 443). When a web page makes a request to a different origin than its own, the browser enforces CORS policies to prevent potential security vulnerabilities.
Imagine you have a website hosted at example.com
. If you want to fetch data from an API located at api.anothersite.com
, your browser will initiate a CORS check. This is because the protocol, domain, and potentially the port are different.
How CORS Works:
When a browser makes a cross-origin request, it adds an Origin
header to the request. This header indicates the origin of the requesting page. The server receiving the request then checks its CORS configuration. If the server allows access from the requesting origin, it responds with specific HTTP headers indicating permission. The most important of these headers is Access-Control-Allow-Origin
.
Example Scenario (Denied Request):
Request: A JavaScript script on
example.com
makes afetch
request toapi.anothersite.com
.fetch('https://api.anothersite.com/data') .then(response => { if (response.ok) { return response.json(); } else { throw new Error('Network response was not ok'); } }) .then(data => console.log(data)) .catch(error => console.error('Error:', error));
Server Response (Without CORS Headers): The server at
api.anothersite.com
responds with the requested data but does not include the necessary CORS headers likeAccess-Control-Allow-Origin
.Browser Action: The browser blocks the response even though the server technically sent the data. The JavaScript code will encounter an error in the
catch
block. This is a CORS error. You’ll likely see a message in your browser’s console similar to: “No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”
Example Scenario (Successful Request):
Request: The same JavaScript
fetch
request is made.Server Response (With CORS Headers): This time, the server at
api.anothersite.com
includes theAccess-Control-Allow-Origin
header in its response:Access-Control-Allow-Origin: https://example.com
Browser Action: The browser, seeing the appropriate CORS header allowing access from
example.com
, processes the response and makes the data available to the JavaScript code.
Other Important CORS Headers:
Access-Control-Allow-Methods
: Specifies the allowed HTTP methods (e.g., GET, POST, PUT).Access-Control-Allow-Headers
: Specifies allowed request headers.Access-Control-Allow-Credentials
: Indicates whether credentials (cookies, authorization headers) should be included in the request. Requires settingwithCredentials: true
in yourfetch
call.
Preflight Requests (OPTIONS):
For certain “complex” requests (e.g., POST requests with content types other than standard form data), the browser might send a “preflight” OPTIONS
request before the actual request. This allows the server to indicate whether it supports the requested method and headers.
By understanding CORS, developers can troubleshoot cross-origin request issues and configure servers to securely allow access to their resources from different origins.