A Brief Overview of Cross-Origin Resource Sharing (CORS)

Oct 9, 2019

CORS is a protocol that helps browsers determine whether it is safe to make an HTTP request to a different origin. Browsers restrict cross-origin requests from JavaScript, so if you use fetch() or Axios to make a request to an Express server that doesn't use CORS, you'll see the below error message:

Access to fetch at 'http://localhost:3000/' from origin 'http://localhost:5000' has been blocked by CORS policy: 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.

What Qualifies as Cross-Origin?

You can think of your origin as what shows up in the URL bar in your browser. For example, suppose you have a browser tab open to http://localhost:5000/tutorials/fundamentals/pojo.

The following are considered cross-origin requests:

  1. https://localhost:5000/test - Different protocol, http vs https
  2. http://localhost:3000/test - Different port, 3000 vs 5000
  3. http://google.com:5000/test - Different host, localhost vs google.com

In other words, any request whose protocol, host, and port don't match what's in the URL bar is considered cross-origin.

Setting Up CORS Support

You need to set up CORS on the server, like using the cors plugin for Express. If you're trying to make an HTTP request to a server that you don't have access to, your only option is to create a proxy.

Most browsers make a preflight request using the HTTP OPTIONS request method (as opposed to GET or POST) to check for CORS headers. In order to support CORS, your server needs to handle OPTIONS requests and set the Access-Control-Allow-Origin header on the response.

Normally you would just use the cors npm module, but this example shows how you can support cross-origin requests by simply setting response headers, which should be easy in any web framework.

const app = require('express')();

// Need to handle 'OPTIONS' requests for pre-flight
app.options('*', (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.send('ok');
});

// As well as set 'Access-Control-Allow-Origin' on the actual response
app.get('/', (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.send('Hello, World!')
});
const server = await app.listen(3000);

Did you find this tutorial useful? Say thanks by starring our repo on GitHub!

More Fundamentals Tutorials