CORS is an abbreviation for Cross-Origin Response Sharing. It is what allows the website on one URL to request data from a different URL, and it frustrates both the frontend and backend devs alike. You might’ve added an image URL only to end up with something like this.
Or, your API fails and shows a CORS error in the console.
This happens because the same-origin policy is part of the browser’s security model which allows websites to request data from APIs of the same URL but blocks those of different URLs. Browsers do this by adding an ORIGIN key in the request.
However, let’s say if the server was on bar.com then the browser will prevent showing this to the client because it had a cross-origin response.
It is to prevent cross-site request forgery. Let’s say you log in to facebook.com and your browser stores the authentication token so that in the future you get logged in automatically. And for every request to the origin facebook.com, these auth-token headers will be present. Now imagine a scenario where you click on a pop-up opening badSite.com. They also have the ability to make requests to facebook.com. In this case, the browser will add related cookies and your token will be shared with badSite.com, and your account has been successfully hacked with a cross-site request forgery attack. To prevent this the CORS error was introduced.
The first method is the quickest, but it is not the right way. It is mostly used during development when you need to start implementing the API quickly and can wait a bit for the final production build. As you might have guessed, we are going to tell the browser to stop caring about these errors. This can be done by installing a chrome extension.
Once installed, click on it and make sure it says on. Once done just refresh your app.
As you can see, whatever this extension did was to stop YOUR browser from checking the CORS error. But when you deliver it to your client this won’t work.
Now, If you are in control of the server then lucky for you because you actually have some power to solve this. But if not, then you are out of luck.
For example, if you want to solve this on the express.js then all you have to do is use a certain middleware that will handle the origin key.
1 2 3 4 5 6 7 8 9 10 11 12
const express = require('express'); const app = express(); const cors = require('cors'); app.use(cors({ origin: 'https://foo.com' })); app.get('/', (req, res) => { res.send('CORS solved') })
But, for any non-standard HTTP request like PUT, PATCH, DELETE, you’ll have to preflight them. The term preflight is used because it’s like a security check before you board a plane to make sure the passengers (or request) are safe to deploy on the airplane (or server) or not. The neat thing is that the browser automatically knows when to preflight and the server responds accordingly whether these non-standard requests are allowed or not.
And at this point, these requests can happen properly. This sounds inefficient, because your service will have to deal with this at every request but the server has an option to respond with a header called Access-Control-Max-Age:86400 which will keep these details saved for the specified time.
Open a network tab in your console.
In the response header look for the Access-Control-Allow-Origin header. If it does not exist then add it as a middleware in the way we discussed above. If it does exist then make sure there is no URL mismatch with the website.
And if all is fine then check whether it is a non-standard HTTP request and you need to allow them.
Let’s say in your express app you only want to allow requests from www.example1.com www.example2.com and www.example3.com.
You will do it in the following way with the help of middleware.
1
2
3
4
5
6
7
8
app.use((req, res, next) => {
const allowedOrigins = ['www.example1.com', 'www.example2.com', 'www.example3.com'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
return next();
});
Now, let’s look at the Access-Control header family with a bit of detail. You can do various things and put several restrictions with their help.
For example you can allow only certain types of requests in the following way.
res.header('Access-Control-Allow-Methods', 'GET, POST');
This will allow only GET and POST requests.
If you want to fix the headers that can be sent by client then you can do that in the following way.
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
If you want the browser to expose things like cookies/authorization headers, or the TLS client certificates then you can do that in the following way.
res.header('Access-Control-Allow-Credentials', true);
These are some of the popular Access-Control header family members.
Goodbye.