False Alarm of CORS Error
Adam C. |

Photo By; Arash Asghari

CORS error is very common when your application is using cross-domain APIs. The error message shown in your browser console is like below:

Access to fetch at ‘https://your-api.com" from origin “https://your-site.com” has been blocked by CORS policy: No ’Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response servers your needs, set the request's mode to ‘no-cors’ to fetch the resource with CORS disabled.

The key part of this message is: No ’Access-Control-Allow-Origin' header is present on the requested resource. To know if you have this issue, check out these two questions:

  1. Are the requesting site and the requested resource (i.e. API server) Cross-Origin? Which includes the different protocols (ex: http vs https) and/or the different domains and or the different ports.
  2. Does the requested resource send the “Access-Control-Allow-Origin” header in the response?

If you say yes to the first question, but say no to the second one, then you would need to fix this by setting up the CORS option in your response header. The solution could be different based on what API server you are using. For example, with the Apollo server, you can have options like below:

const options = {
  cors: {
    origin: *,
    credentials: true,
    methods: 'POST, GET, OPTIONS',
    allowedHeaders: [
      'Content-Type',
      'X-Amz-Date',
      'Authorization',
      'X-Api-Key',
      'X-Amz-Security-Token'
    ]
  }
};

If you say yes to both questions, then very likely you're okay, and the CORS error is just a false alarm.  In this case, you need to check the request and response header of your API (XHR) call, which can be found at the ‘Network’ tab of the browser's Inspect tool. 

You might see some Request Headers like:

Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site

This means the request is made by cross-site with ‘cors’ mode, so the browser will look for ‘Access-Control-Allow-Origin’ header in the response to make sure the request is allowed under CORS policy. When the header is not present, the browser will throw the error with the Eye-catching word “CORS”. It would be very confusing if you believe that you have CORS set up already, either open to everyone (with ‘*’) or to the whitelist of domains.

Most likely, there are some other issues of your API server, for example, database connection issue or network issue, which causes “500” internal error, but the response headers of status 500 do not include “Access-Control-Allow-Origin”, so the browser throws the error no matter what.

Worth to mention that the second part of the error message is even confusing:

If an opaque response servers your needs, set the request's mode to ‘no-cors’ to fetch the resource with CORS disabled.

You should know that setting “no-cors” as the request's mode does not help you to get cross-domain resource at all. Basically, it tells the browser that “Please don't show me any ‘cors' resource. ” I am 99.99% sure that it is not what you wanted. So just forget it. If you really wanted to know what it's like I did. Try to read this resource 10 times.  Be honest, I am still not very sure why we need “no-cors”.