CORS in React: Wat het is, waarom het belangrijk is, en hoe je het inschakelt
Inzicht in CORS in React
CORS is al lange tijd een bron van verwarring—en frustratie—voor developers, vooral voor wie net begint. Het concept kan lastig te doorgronden zijn, zeker wanneer je single-page applications (SPA’s) bouwt met frameworks als React, Angular of Vue en probeert te communiceren met externe API’s.
In deze gids help ik je CORS vanaf de basis te begrijpen. We bouwen een eenvoudige React-app naast een Express-server om te laten zien wat CORS-fouten triggert en waarom ze optreden. Belangrijker nog: ik laat je de verschillende manieren zien om deze issues op te lossen—zowel in het algemeen als specifiek binnen een React-omgeving.
Wat is CORS?
CORS, of Cross-Origin Resource Sharing, is een protocol dat regelt hoe webapplicaties resources opvragen van servers die op andere origins gehost worden. Net zoals HTTPS regels definieert voor veilige communicatie, stelt CORS de regels vast voor cross-origin requests.
Moderne webapps zijn doorgaans opgesplitst in twee kernonderdelen: de client (de frontend die in je browser draait) en de server (meestal een API of backendservice). De client stuurt requests naar de server—bijvoorbeeld om data op te halen—en de server stuurt een response terug. CORS komt in beeld wanneer deze twee delen op verschillende domeinen, poorten of protocollen leven.

Waarom deze architectuur zo gangbaar is
Deze ontkoppelde architectuur—waarbij de frontend en backend als aparte applicaties worden ontwikkeld en gedeployed—wordt steeds populairder. Een groot voordeel is flexibiliteit: je backend kan meerdere typen clients bedienen, waaronder webapps, desktopinterfaces, mobiele apps of zelfs IoT-devices. Elke client kan dezelfde API’s consumeren zonder strak gekoppeld te zijn aan de presentatie-laag.
De Same-Origin Policy en cross-origin requests
Omdat de client en server aparte applicaties zijn, worden ze doorgaans op verschillende domeinen, poorten of protocollen gehost. Dit betekent dat zelfs wanneer je eigen frontend probeert te communiceren met je eigen backend, de browser het verzoek als cross-origin kan beschouwen.
Dit komt nog vaker voor wanneer je met third-party services werkt—voor authenticatie, analytics, betaalgateways, en meer. In al deze gevallen moet je frontend met een andere origin communiceren door HTTP-requests te versturen.
En hier zit ’m de crux: moderne browsers handhaven een beveiligingsmechanisme genaamd de Same-Origin Policy, dat beperkt hoe scripts die op de ene origin draaien kunnen interacteren met resources van een andere. Daar komt CORS om de hoek kijken—het is een mechanisme dat die cross-origin requests op een veilige manier mogelijk maakt.

Waarom browsers cross-origin requests blokkeren
Wanneer je webapplicatie een resource van een andere origin probeert op te vragen—zoals een ander domein, een andere poort of een ander protocol—handhaaft de browser een beveiligingsfunctie die bekendstaat als de Same-Origin Policy (SOP). Dit beleid is ontworpen om te voorkomen dat mogelijk malafide websites zonder toestemming toegang krijgen tot gevoelige data op een andere origin.
Historisch gezien maakte dit het web veel veiliger. Een script op xyz.com
kon bijvoorbeeld niet stiekem persoonlijke data van abcbank.com
binnenhalen, waarmee gebruikers werden beschermd tegen cross-site-aanvallen. De Same-Origin Policy blokkeert echter ook legitieme use-cases—zoals wanneer je React-app op localhost:3000
data probeert te fetchen van een API die draait op localhost:8080
of van een externe service.
Daar is CORS: de oplossing voor SOP-beperkingen
Hier komt CORS—Cross-Origin Resource Sharing—in beeld.
CORS is een protocol dat de Same-Origin Policy versoepelt onder gecontroleerde voorwaarden. Het stelt servers in staat—via specifieke HTTP-headers—aan te geven dat bepaalde cross-origin requests veilig zijn en toegestaan worden.
Dus wanneer je clientapplicatie een request maakt naar een andere origin, kan de server antwoorden met een speciale set CORS-headers. Deze headers werken als een “toestemmingsbriefje” dat de browser vertelt: “Dit cross-origin request is toegestaan.” Daardoor blokkeert je browser de response niet meer en wordt de resource succesvol gedeeld.

Wat gebeurt er wanneer CORS is ingeschakeld?
Zodra je browser de CORS-headers in de response van een server detecteert, staat hij toe dat je applicatie de data benadert—ook als de origin van het request verschilt. Dat is de essentie van CORS: gecontroleerde toegang tot resources over verschillende origins.
Nu je een solide begrip hebt van wat CORS is en waarom het nodig is, lopen we door een hands-on voorbeeld om het in actie te zien. Als je nog dieper wilt duiken, kun je altijd deze uitgebreide CORS-gids bekijken voor extra details.
🛠️ Stap 1: Maak een Express-server met API-endpoints
Om te demonstreren hoe CORS werkt, hebben we nodig:
-
Een client (gebouwd met React) die HTTP-requests maakt
-
Een server (gebouwd met Express) die API-endpoints aanbiedt om op die requests te reageren
⚠️ Om een echt CORS-scenario te triggeren, moeten client en server op verschillende origins draaien—bijvoorbeeld verschillende poorten zoals localhost:3000
en localhost:8080
.
🧱 Server opzetten
Laten we beginnen met het maken van een basis Express-server.
-
Maak de projectmap:
mkdir cors-server && cd cors-server
-
Initialiseer een nieuw Node.js-project:
npm init -y
Dit maakt een package.json
aan met standaardwaarden.
-
Installeer Express:
npm install express
-
Maak het app-entry-bestand:
Maak een bestand app.js
in de hoofdmap en voeg de volgende code toe:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Welcome to CORS server 😁');
});
app.get('/cors', (req, res) => {
res.send('This has CORS enabled 🎈');
});
app.listen(8080, () => {
console.log('Listening on port 8080');
});
Dit is een minimale Express-server met twee endpoints:
-
/
geeft een welkomstbericht terug. -
/cors
simuleert een resource-endpoint dat je vanuit je React-app zou fetchen.
-
Start de server:
node app
Als hij draait, bezoek dan http://localhost:8080/ in je browser; je zou dit moeten zien:
Welcome to CORS server 😁
En als je http://localhost:8080/cors bezoekt, zie je iets als dit:

⚛️ Stap 2: Zet de React-app op
Nu onze Express-server draait, is het tijd om een eenvoudige React-app te maken die HTTP-requests naar die server doet—en expres een CORS-fout triggert zodat we leren hoe we die oplossen.
📦 Maak een nieuw React-project
Voer, in een aparte directory van je server, het volgende commando uit:
npx create-react-app react-cors-guide
Dit scaffolldt een basis React-app in een map genaamd react-cors-guide
.
Als dit klaar is, ga naar de projectmap en open het bestand src/App.js
. Vervang de inhoud door de volgende code:
import { useEffect } from 'react';
import './App.css';
function App() {
const makeAPICall = async () => {
try {
const response = await fetch('http://localhost:8080/', { mode: 'cors' });
const data = await response.json();
console.log({ data });
} catch (error) {
console.error('CORS error:', error);
}
};
useEffect(() => {
makeAPICall();
}, []);
return (
<div className="App">
<h1>React CORS Guide</h1>
</div>
);
}
export default App;
🧠 Wat gebeurt hier?
-
We definiëren een functie
makeAPICall
die eenGET
-request doet naarhttp://localhost:8080/
met de Fetch API. -
De optie
{ mode: 'cors' }
vertelt de browser expliciet dat dit een cross-origin request is. -
De
useEffect
-hook zorgt ervoor dat het request wordt getriggerd zodra de<App />
-component mount.
🔥 Reken op een CORS-fout
Als je de React-app start met:
npm start
En je de devtools-console van je browser bekijkt, zie je waarschijnlijk een CORS-fout die er ongeveer zo uitziet:
Access to fetch at 'http://localhost:8080/' from origin 'http://localhost:3000' has been blocked by CORS policy.
Dit is de Same-Origin Policy van de browser die z’n werk doet: toegang blokkeren tot een resource van een andere origin.

De CORS-fout begrijpen
De fout die je in de browserconsole zag, is een klassiek CORS-probleem. Hoewel zowel je client als je server op localhost
draaien, gebruiken ze verschillende poorten—React op localhost:3000
en Express op localhost:8080
.
Dit betekent dat ze volgens de Same-Origin Policy (SOP) als verschillende origins worden beschouwd, en de browser het request om veiligheidsredenen blokkeert.
⚠️ Typisch CORS-foutbericht
Dit is waarschijnlijk wat de browser meldde:
Access to fetch at 'http://localhost:8080/' from origin 'http://localhost:3000'
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.
Laten we dit ontleden:
-
De browser blokkeert de response omdat hij geen
Access-Control-Allow-Origin
-header vond in de response van de server. -
Er wordt zelfs een workaround gesuggereerd—de fetch-mode op
'no-cors'
zetten—maar dat levert een beperkte, “opaque” response op waar je niets mee kunt. -
En cruciaal: je client deed niets fout. CORS is geen client-side error—het is een door de browser afgedwongen regel op basis van hoe de server antwoordt.
✅ CORS hoort je altijd op de server op te lossen
Omdat de serverresponse bepaalt of de browser toegang toestaat, is de juiste oplossing je server zo te configureren dat hij de correcte CORS-headers terugstuurt.
Je kunt CORS tijdens development aan de clientkant omzeilen met proxies, maar de nette, production-veilige aanpak is CORS rechtstreeks op de server in te schakelen.
🔧 CORS inschakelen op de Express-server
Ga terug naar app.js
in je Express-server en werk het /cors
-endpoint bij:
app.get('/cors', (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.send({ msg: 'This has CORS enabled 🎈' });
});
Dit gebeurt er:
-
De header
Access-Control-Allow-Origin
wordt gezet op*
, wat betekent dat elke origin toegang heeft tot deze resource. -
Dit is een snelle en makkelijke manier om CORS voor demo-doeleinden in te schakelen. (Later kun je toegang beperken tot specifieke origins.)
🔁 De React-client bijwerken
Ga nu terug naar je React-app en update de fetch-URL om het nieuwe endpoint aan te spreken:
const response = await fetch('http://localhost:8080/cors', { mode: 'cors' });
Sla je wijzigingen op en herstart indien nodig de React-devserver.
🧪 Testen maar
Open je browser en refresh de app. Deze keer zou de browser de response moeten doorlaten en zie je in je console het volgende gelogd:
{ data: { msg: 'This has CORS enabled 🎈' } }
Gelukt! Je hebt zojuist je eerste cross-origin request gedaan met correct geconfigureerde CORS.

De fix bevestigen: CORS werkt!
Zodra de CORS-header correct op de server is ingesteld, verdwijnt de fout en ontvangt je React-app de response als JSON. 🎉 Alles werkt zoals verwacht! Vergeet alleen niet—je moet je backendserver mogelijk herstarten nadat je wijzigingen hebt aangebracht, voordat ze effect hebben.
🎯 CORS beperken tot specifieke origins
In plaats van een wildcard (*
) te gebruiken—waarmee elke origin toegang krijgt tot je resources—kun je CORS beperken tot een specifiek domein, bijvoorbeeld je React-developmentserver:
app.get('/cors', (req, res) => {
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
res.send({ msg: 'This has CORS enabled 🎈' });
});
Dit is aan te raden voor productie om te voorkomen dat onbevoegde websites je API benaderen.
⚠️ Wanneer je de server niet kunt aanpassen
Hoewel het aanpassen van de server de netste en meest robuuste manier is om met CORS om te gaan, is dat niet altijd een optie. Veel developers lopen hiertegenaan bij het gebruik van third-party API’s—voor authenticatie, notificaties, e-mailservices, en meer. In die gevallen kun je het CORS-beleid van de server niet wijzigen.
Als dat gebeurt, lijk je vast te zitten… of toch niet?
🧞♂️ Workaround: een proxy gebruiken in React
Hier is een slimme workaround specifiek voor React-development: proxy je API-requests via de developmentserver.
Zie proxying als het bij de presentielijst “aanwezig” antwoorden voor een klasgenoot—je app doet alsof het verzoek van een andere bron komt (d.w.z. de origin van de server), waardoor de SOP-beperkingen van de browser worden omzeild.
✏️ Zo stel je een proxy in
-
Open je
package.json
in de root van het React-project. -
Voeg een
proxy
-veld toe:
{
...
"proxy": "http://localhost:8080"
}
-
Herstart je React-devserver (
npm start
); nu worden alle requests stilzwijgend via de backend gerouteerd.
Wanneer je bijvoorbeeld data fetcht van /cors
:
const response = await fetch('/cors');
Dan wordt dit intern geproxied naar http://localhost:8080/cors
, waardoor het request voor de browser “same-origin” lijkt.
🧪 Wil je een third-party service gebruiken?
Geen probleem! Daar kun je ook naartoe proxien:
{
...
"proxy": "https://randomservice.com"
}
Houd rekening met het volgende:
-
Alleen niet-HTML-requests (doorgaans API-requests) worden geproxied.
-
De
Accept
-header van je request mag niettext/html
zijn. -
Voor complexere setups (bijv. meerdere proxies) gebruik je http-proxy-middleware om custom proxy-gedrag te configureren.
🧹 Afronden: best practices voor CORS in React
Onthoud voor CORS het volgende:
-
Los CORS altijd op server-niveau op—dat is de meest betrouwbare, veilige oplossing.
-
Tijdens development kan React’s proxy-setup helpen CORS-issues te vermijden zonder serverwijzigingen.
-
Als je de API-server niet beheert, neem contact op met de provider—of gebruik een eigen proxyserver.
-
Tools zoals CORS Unblock Chrome-extensies kunnen tijdelijk werken, maar moeten nooit in productie worden gebruikt.
-
Specificeer in je fetch-requests altijd
{ mode: 'cors' }
om het gedrag expliciet te houden. -
Begrijp dat de meeste browser-workarounds niet meer werken zodra je deployed—plan vroeg voor productie.