%% date:: [[2021-06-09]], [[2021-02-18]], [[2023-05-13]] parent:: %% # [[Cross-Origin Resource Sharing]] Cross-Origin Resource Sharing is often abbreviated as CORS. It is a headers-based security mechanism employed to prevent resources from being retrieved by domains other than those explicitly set in an allowlist, including scripts. [^mdn] Typically, browsers have a _same-origin policy_ as a security restriction, preventing web pages from making a request to a different domain. It's meant to prevent third parties from accessing sensitive information. [^microsoft] CORS is generally a good thing... except when it gets in the way in the following circumstances: - you're trying to test a system that doesn't have convenient API endpoints. - you're developing an integration or extension to a system that you don't own. - you want to be able to programmatically access your own account data on a third-party platform. - you're developing a local application but trying to connect to resources stored elsewhere. Here's an example of a console error due to this issue: ``` Access to XMLHttpRequest at 'file:///Users/nic/git/dndgen/dnd/js/JSON/magic-item-homebrews.json' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https. ``` ## Structure of CORS CORS involves: ### A PREFLIGHT request You can think of the preflight request as a way to ask for the permission to use certain HTTP methods under CORS. Here's an example of a header that a preflight request might have: ``` 'access-control-request-method': 'POST', ``` And a typical [[HTTP Response Codes|HTTP response code]] would be 204 (No Content), which contains the following response header: ``` 'Access-Control-Allow-Methods': 'POST' ``` After a successful preflight request, a main request can be made. However, some requests don't trigger a preflight. ### A main request The main request can then proceed as normal, except usually with a `origin` or `X-Requested-With` header. ## Getting around CORS There *are* ways to get CORS to allow requests to a different domain under certain conditions. These conditions are set in the [[W3C]] standards and involve certain headers being sent with a request. The problem is that the same-origin policy restrictions are triggered when testing, for example, a web application stored locally, especially when it attempts to access other local files. Yet the CORS policy cannot take effect without adding headers to every response. ### Run Chrome under a different flag The best way to prevent this from happening is to run this command to open a Chrome window that allows CORS: `open /Applications/Google\ Chrome.app --args --allow-file-access-from-files &` ### Use a [[Reverse Proxy]] If you need to access a resource programmatically and you want to do so on the protocol level rather than on the browser level, you can use a reverse proxy to sit between your client and the application so that your client never makes direct requests to the application itself. In this case, the reverse proxy can add CORS headers to every request you make, so that you don't have to do it. [Cors-Anywhere](https://github.com/Rob--W/cors-anywhere) is a [[NodeJS]] app that you can deploy as a reverse proxy. It used to be publicly available, but for security reasons, access to it is now granted only temporarily, to reinforce the fact that it's not meant to be used for nefarious purposes. Instead, the author recommends that you host it yourself. I [[Deploy a NodeJS app on DigitalOcean|deployed it]] on [[DigitalOcean]] as a [[Setting up Nginx as a reverse proxy|reverse proxy]]. ## References [^microsoft]: https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-5.0#how-cors [^mdn]: Mozilla (MDN). *Cross-Origin Resource Sharing (CORS) - HTTP | MDN*. Retrieved on May 13, 2023 from https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)