Fetching data from client-side JavaScript isn’t as trivial as it seems. Although it works in Postman, using mode: 'no-cors'
in your code won’t disable CORS and leaves you with an opaque response. This article will show you the right approach to handle it.
Problem Statement
When hitting the endpoint
http://catfacts-api.appspot.com/api/facts?number=99
using Postman, it returns JSON without any issues. However, when you try to fetch the same endpoint from your client-side code, you run into this error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
So you try to disable CORS by adding an options object to your fetch call like this:
fetch("http://catfacts-api.appspot.com/api/facts?number=99", {
mode: "no-cors",
})
.then((blob) => blob.json())
.then((data) => {
console.table(data);
return data;
})
.catch((e) => {
console.log(e);
return e;
});
But that just gives you another error. It seems like you just want to disable CORS, but something isn’t working.
Solving "Trying to use fetch and pass in mode: no-cors"
The short version is that mode: 'no-cors'
isn’t a magic fix. Instead of bypassing CORS, you end up with an “opaque” response that hides everything, including headers and body content. Here's what’s really happening:
CORS Basics
By default, browsers block cross-origin requests unless the server explicitly sends an Access-Control-Allow-Origin
header. Without that header, your code can’t access the response data, even though tools like Postman or your browser’s dev tools might show the full response.
What Can You Do?
Instead of trying to disable CORS directly (which isn’t really possible on the client side), you need to use a proxy. A CORS proxy will:
- Receive your request and forward it to the destination server.
- Get the response from the server.
- Inject the necessary
Access-Control-Allow-Origin
header into the response. - Pass the updated response back to your client code.
For example, you can use a self-hosted option like cors-anywhere, or preferably use a production ready proxy like Corsfix to handle the CORS headers for you.
const corsProxyUrl = "https://corsfix.com/";
const targetUrl = "http://catfacts-api.appspot.com/api/facts?number=99";
fetch(`${corsProxyUrl}${targetUrl}`)
.then((response) => {
if (!response.ok) {
throw new Error(
`Network response was not ok, status: ${response.status}`
);
}
return response.json();
})
.then((data) => {
console.table(data);
return data;
})
.catch((e) => {
console.log(e);
return e;
});
When you say you want to “disable CORS,” what you’re really trying to do is work around the same-origin policy. CORS provides a controlled way to relax that policy, but you can’t simply switch it off in a production environment. The proxy solution is the way to go because it works for all users of your app, not just your local setup.
Conclusion
In summary, rather than trying to disable CORS on the client side with no-cors
, use a proxy to handle the request. This approach allows your frontend to access the data properly while still respecting the browser’s security model. Corsfix is free to get started, use it to solve your CORS issues easily when devloping your app.
Originally asked by dwww and answered by sideshowbarker on StackOverflow.
Top comments (1)
have you ever used a proxy to bypass CORS before?