Request succeeds on server but results in CORS error in browser

You already tagged your post correctly with "cors". Modern browsers does not allow accessing endpoints across domains, unless the endpoint sends cors-headers which allows you to access it.

If you check your network tab, there should be an OPTIONS-request to https://login.microsoftonline.com/common/oauth2/v2.0/token. This s called he preflight-request, which checks for Access-Control-Allow-Origin and Access-Control-Allow-Methods headers. Access-Control-Allow-Origin must contain your domain or *, and Control-Allow-Methods must contain POST or *.

I'm not familiar with the office apis, but i think there must be a way to configure your app as an valid endpoint. Perhaps this post will help you: https://msdn.microsoft.com/en-us/office/office365/howto/create-web-apps-using-cors-to-access-files-in-office-365


What you’re seeing is expected behavior when sending a cross-origin request to a server but not receiving the Access-Control-Allow-Origin response header in the response.

Specifically, as long as your cross-origin request has no characteristics that cause your browser to do a preflight OPTIONS request before making your request, then the request will succeed on the server side — but, because the response from the server to that request doesn’t include the Access-Control-Allow-Origin response header, your browser blocks your frontend code from being able to actually see the response the server sends.

However, if you open browser devtools you can still see the response there. But just because the browser received the response and you can see it in devtools, it doesn’t mean the browser will expose the response to your code. It’ll only expose it when it has Access-Control-Allow-Origin.


That all may seem counter-intuitive but it all makes sense if you remember that the browser is the only point at which cross-origin restrictions are enforced. Servers don’t block cross-origin requests.

When the server you’re sending that request to receives the request, it doesn’t check the origin to decide whether to respond. The server just accepts the request and processes it and then sends a response. But then the browser blocks your code from access to that response.

But it’s also important to remember that the browser doesn’t block your code from sending that request cross-origin. Browsers only block cross-origin requests from being sent when the requests have qualities (like special headers) that trigger the browser to do a preflight.

So if your request isn’t one that triggers a preflight, the browser sends it and the server receives it and processes it. And if the request method is POST or some other whose purpose is to change state on the server — in which case you may not care much what the response is — then to the degree that the request had the intended effect on the server side, it can be considered successful.

But consider what happens when you do actually care a lot what the response is: Consider what happens for GET requests, where the entire point of making the request is to get back a response.

As explained above, if the request isn’t one that triggers a preflight, the browser sends it, the server receives it, and returns a response. But if the response doesn’t include the Access-Control-Allow-Origin response header, your browser won’t let your frontend JavaScript code access it.

Obviously since the entire point of making a GET request is to do something with the response, then in that case if your code can’t access the response, that’s a hard, total failure — in contrast to the case of the POST request, where the request body does actually still get posted as expected, but you just don’t have a way for your code to check the response to see if the request succeeded.