Access to XMLHttpRequest has been blocked by CORS policy

I’m having a weird problem where the first call to an API from UI-builder throws a CORS error -

My code has a loop to call the API up to three times. The first time always fails, but the second call works. This is the section of the code -

I’m confused why it would fail and then work.

Hi @Tim_Jones

try to copy these requests as cURLs and compare them to find the difference

Hi @vladimir-upirov

I’m not following. There is a single request.

Tim

I thought it does 3 requests, doesn’t it?

The same call is made up to three times in the event of an error.

This is what is happening:

Loop -
Attempt 1 - Errors because of the CORS policy issue
Attempt 2 - Works

The same code is being run for all the attempts.

I understand that, but since you build your requests dynamically we should start with finding a difference between each shot, in case these requests are entirely identical you need to contact the service you run requests to

to copy a request as a cURL you need to open the browser dev tool, select the Network tab and using the context menu copy these cUrl and put them somewhere in a text editor for comparison

The calls are identical; I checked that first.

I also figured out that all the calls fail, but a CORS browser extension I am running was allowing the second call to process. When I disabled it all the calls fail.

I created a Cloud code copy of the exact code (slight modifications to var names) and it runs fine. So the issue is coming from the API call from the browser, which is what I understand CORS to be, a browser policy.

I don’t understand why you’re suggesting I need to contact the service the requests are sent to.

Tim

CORS error comes from the browser because this request goes to a different domain, and before sending an actual GET request it sends an OPTIONS request to verify if the external service is able to process a request from another domain, if so it should return a corresponding header. but the external server seems like doesn’t allow requests from another domain.

I understand that in concept. In testing, the calls are coming from a test backendless domain (magicaljelly), however, In production, the requests are both from subdomains of our main domain.

sub1.OurDomain.com (UI builder/Backendless) makes a call to sub2.OurDomain.com (Our API endpoint).

Tim

I just doubled check your error, it says the header “content-type” is not allowed, have you tried to remove it from the request?

That is a good idea. I tried that and now it fails on the ApiKey, which is needed for authentication -

Request header field apikey is not allowed by Access-Control-Allow-Headers in preflight response.

does this fail on the OPTIONS request?

I can propose you two options:

  1. contact the service community to find out why it fails with CORS, perhaps there is a need to add your backendless domain to a white list on the service

  2. create an API Service and use it as a proxy and call the API service from the UIBuilder app

How would I know if it is failing on the OPTIONS request?

  1. contact the service community to find out why it fails with CORS, perhaps there is a need to add your backendless domain to a white list on the service

It is an API running on our server. The server has no issue with API calls from Cloud code. What I want to understand is why is there a difference between Cloud code calls and browser calls?

2. create an API Service and use it as a proxy and call the API service from the UIBuilder app

I’ve done this already as a test. It adds 500-700 ms to the load time, which I’d like to avoid.

Tim

When a page is loaded by the browser from host X and the same page makes a request going to host Y, the browser imposes a CORS policy by issuing the OPTIONS request to ensure the subsequent (actual API) request can go through. This does not happen when the same request is executed from the server-side environment.

Ah! Thank you, @mark-piller. I appreciate your clear explanation of what is happening.

So I need the API endpoint server to respond to the OPTIONS preflight request so the browser knows the call will go through. Is that right?

Yes, your server needs to handle the OPTIONS request gracefully and return a response that will let the other actual API request go through.