The Worst Four-Letter Word in Bootcamp: CORS
Few words (or acronyms rather) strike fear in the hearts of budding web developers like CORS. In 2022, I decided to learn web development and in the past year, I've run into my fair share of CORS errors and have seen countless pained LinkedIn posts, discord threads, and tweets regarding the dreaded CORS error.
Now in my first job as a web developer, I'm managing a RESTful API and have implemented CORS policies myself, so I thought I'd break down some of the lessons I've learned to help anyone banging their head against their screen like I did so many times. We'll take a look at what CORS is, how you can solve CORS issues, and why there's a dead simple way to not encounter CORS issues in the first place.
"Access to fetch at 'https://iwasreallyhopingtousethis.com/api/inyourdreams' from origin 'http://www.thisissopainful.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
Cross-Origin Resource Sharing, or CORS, is an implementation of HTTP requests that allows a server to make exceptions to the "same-origin policy" implemented by web browsers to block cross-site forgery attacks. In short, the same-origin policy blocks HTTP requests for resources from domains other than the website you're currently browsing to ensure would-be hackers can't take advantage of any valid cookies that might be hanging around in your browser's memory at the moment.
Because the same-origin policy is the default policy within modern browsers, any request made from a resource that doesn't explicitly allow requests from other domains will be blocked. What's confusing is that a CORS error isn't so much a bug in your code, but a setting in the API you're calling.
If an API would like to allow other cross-origin requests of their resources (think any fully public API like the OpenWeatherAPI), they can set up a wildcard policy that allows requests from any origin.
For a little more fine-grained control, an API maintainer could explicitly allow specific methods (PUT, DELETE, etc) from specific origins.
So what happens when you don't maintain the API yourself? How can you make requests past this annoying but important browser policy? The answer isn't that you need to install some plugin on your browser or other work-around, it's that you should be running your API calls on the server side of your application.
In almost every case I've come across, CORS issues popped up where a developer (mostly me) tried to make API calls from the front end of an application where they should have been calling from the back end. In many cases, perhaps you have some sort of authentication token you need to use anyway -- these calls should be made from your back-end server.
If you have a project open with a CORS error right now, open up your terminal, cd into the folder where your project is, and use Node to run your file rather than spinning up a server and running your script from your HTML. It's probably something like:
node script.js
Did that fix your issue? I'll bet in most cases it did.
In the rush to crank out full-stack developers, boot camps and other fast-paced learning resources often teach you how to make fetch requests from the browser. It makes a bit of sense --you're already familiar with the browser, perhaps you've learned to manipulate the DOM, and many new developers are generally uncomfortable working in the command line.
That said, I believe it's incorrect to teach fetching in the browser. Sure, you'll make plenty of API calls from your front-end applications, but in many cases, it's incorrect and insecure to be fetching in the browser.
To further complicate things, many of the full-stack application frameworks (especially with the current prevalence of server-side components) well-abstract the environment variable process and exactly where and when calls are being made and components rendered.
In short, make your back-end calls on the back end. Spend some time getting familiar with running your JavaScript outside of the browser and in the console/Node. Not only will it save you a lot of frustration, but I find it's a lot faster and more enjoyable than spinning up a server for every request anyway.