A Brief Overview of Cross-Origin Resource Sharing (CORS)
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:
https://localhost:5000/test
- Different protocol,http
vshttps
http://localhost:3000/test
- Different port,3000
vs5000
http://google.com:5000/test
- Different host,localhost
vsgoogle.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);