CORS error: Missing 'Access-Control-Allow-Origin' header when calling external API

I’m working on a web app that needs to get data from an external API service. When I test the API with curl commands, everything works fine and I get the expected response.

But when I try to make the same request using JavaScript fetch API, I keep running into CORS issues. Here’s the error I’m seeing:

Access to fetch 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.

I think the problem is related to cross-origin restrictions since I’m running my app on localhost. I tried adding CORS headers to my request but it doesn’t seem to work. Maybe I’m missing something in my implementation?

function authenticateUser() {
  const requestHeaders = new Headers();
  
  requestHeaders.append('Content-Type', 'application/json');
  requestHeaders.append('Accept', 'application/json');
  
  requestHeaders.append('Access-Control-Allow-Origin', 'http://localhost:3000');
  requestHeaders.append('Access-Control-Allow-Credentials', 'true');
  
  requestHeaders.append('GET', 'POST', 'OPTIONS');
  
  requestHeaders.append('Authorization', 'Basic ' + btoa(userLogin + ":" + userPass));
  
  fetch(apiEndpoint, {
    //mode: 'no-cors',
    credentials: 'include',
    method: 'POST',
    headers: requestHeaders
  })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.log('Request failed: ' + err.message));
}

When I try using a CORS browser extension, I get a different error about wildcard origins not being allowed with credentials. Any ideas what I’m doing wrong here?

It’s a browser security thing - curl doesn’t have those restrictions. I hit the same wall and ended up creating Express middleware on my dev server to proxy the API calls. The browser thinks it’s hitting the same origin while your server does the heavy lifting with external APIs. If you’re using webpack-dev-server, their proxy config works great too. You’ll need a backend proxy for production anyway since browser extensions won’t cut it for real users. Those CORS headers in your fetch? Browser ignores them completely - they need to come from the API server’s response headers.

CORS headers come from the server, not your client code. Adding Access-Control headers to your request won’t fix anything - the browser only cares about what the API server sends back. Since your API works with curl, the server just doesn’t have CORS set up for browser requests. You’ve got a few options: set up a proxy that adds the CORS headers, create a backend endpoint to handle the API calls, or use something like cors-anywhere for testing. Don’t bother with no-cors mode either - you’ll get an opaque response that can’t be read as JSON. For production, you’ll need to either fix the API server’s CORS settings or build a proper backend solution.

yeah, that wildcard + credentials combo is annoying. browsers won’t let you use Access-Control-Allow-Origin: * with credentials: 'include' - the server has to return your actual domain instead of the wildcard. since you can’t control the external api, easiest workaround is either running your dev server on the same origin or just dropping credentials if you don’t really need them.